Как проверить, является ли URL того же происхождения, что и текущая страница и / или работник - PullRequest
0 голосов
/ 11 декабря 2018

Здесь есть похожий вопрос

javascript Как проверить, является ли URL того же источника, что и текущая страница?

К сожалению, в нем не указано, что ответы должны работатькак на странице, так и на рабочем месте, поэтому ни один из ответов не работает на рабочем.

В частности, я пытаюсь использовать API извлечения для извлечения изображений таким образом, чтобы он работал максимально автоматически.Когда изображение выбирается, я хочу установить режим на cors, но только если URL не того же происхождения.Мне нужно знать, как это сделать как в контексте страницы, так и в рабочем контексте.

Псевдокод

function loadImageBitmap(url) {
  const options = {};
  if (urlIsNotSameOrigin(url)) {
    options.mode = 'cors'; 
  }
  return fetch(url, options)
  .then((response) => {
    if (!response.ok) {
      throw response;
    }
    return response.blob();
  }).then((blob) => {
    return global.createImageBitmap(blob);
  });
}

function urlIsNotSameOrigin(url) {
  // what do I put here?
}

// examples
async function main() {
  const bitmaps = Promise.all([
    'https://notsamedomain.com/foo.jpg',
    '../relative/image.png',
    '/absolute/thing.jpg',
    '//other/absolute/thing.jpg',
    'https://samedomain.com/bar.gif',
  ].map(loadImageBitmap));
}
    

Большинство решений, которые я видел, - это создать элемент привязки <a>, назначить свойство src и затем прочитать его.Но якоря не существуют в рабочих.URL объект не обрабатывает относительные ресурсы, как это делает якорь.

1 Ответ

0 голосов
/ 11 декабря 2018

Разница между конструктором URL () и якорным элементом заключается в том, что конструктор URL () не является ни узлом, ниприкрепленный к определенному Document объекту, и поэтому не имеет baseURI , который он может зацепить.

Так что вам нужно, чтобы конструктор URL () вел себя так же, как и якорный элемент , чтобы передать baseURI в качестве второго аргумента конструктора .

Это означает, что в документе new URL(uri, document.baseURI) будет возвращать те же свойства URL, что и Object.assign(document.createElement('a'), {href: uri}), при условии, что URI произведен является допустимым.

Теперь, в Worker у нас все еще нет доступа к Node baseURI , и это довольнонепонятно, что вы хотите зацепить.

В большинстве случаев вы можете просто использовать self.location.href в качестве базового URI, и это на самом деле может быть тем, что вам нужно, если вы собираетесь получать ресурсы того же источника, но если вы действительно инициализируете свой Worker изblobURL, возможно, вам придется пропустить его из основной области, так же, как я это делал в сверхзащищенном фрейме StackSnippet®.

// init worker from a blobURI...
const worker_url = getWorkerURL(worker_script);
const worker = new Worker(worker_url);
worker.onmessage = e => console.log(e.data);

worker.postMessage({
  // we pass the base URL
  base: 'https://samedomain.com/foo.html',
  uris: [
    'https://notsamedomain.com/foo.jpg',
    '../relative/image.png',
    '/absolute/thing.jpg',
    '//other/absolute/thing.jpg',
    'https://samedomain.com/bar.gif'
    ]
});

//__MISC__________
// gets our Worker's blobURL based on a Blob made
// from a <script> element textContent
function getWorkerURL(el) {
  const content = el.textContent;
  const blob = new Blob([content], {type: 'application/javascript'});
  return URL.createObjectURL(blob);
}
<script id="worker_script" type="worker_script">
  onmessage = e => {
    const d = e.data;
    
    // if we weren't in a null origined iframe's blobURI we could do
    //const self_url = new URL(location.href)
    // but here we pass the fake base domain
    const self_url = new URL(d.base);
    const sameorigins = d.uris.filter( uri => {
      try { // wrap in a try-catch, invalids throw
        const url = new URL(uri, self_url);
        return url.origin === self_url.origin;
      } catch(e) { return false; }
    })
    postMessage(sameorigins);
  };
</script>
...