【问题标题】:Failed to execute 'fetch' on 'WorkerGlobalScope'无法在 'WorkerGlobalScope' 上执行 'fetch'
【发布时间】:2020-07-05 06:20:53
【问题描述】:

我试图从网络工作者内部的服务器获取数据。但是每次我在开发工具中遇到同样的错误。

Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'WorkerGlobalScope': Failed to parse URL from /api/books

我看到了this 关于服务人员的回答,但它对我不起作用。

WebWorker 文件代码!

// data-handling.web-worker.js

const workercode = () => {
  onmessage = async e => {
    const res = await fetch('/api/books');

    postMessage(res);
  }
};

let code = workercode.toString();
code = code.substring(code.indexOf('{')+1, code.lastIndexOf('}'));

const blob = new Blob([code], {type: 'application/javascript'});
const worker_script = URL.createObjectURL(blob);

export default worker_script;

在 React 组件中导入。

import data_handling_worker from "./data-handling.web-worker";
const dataHandlingWorker = new Worker(data_handling_worker);

在钩子中运行和发布消息!

const [searchQuery, setSearchQuery] = useState('');
const [booksList, setBooksList] = useState([]);

useEffect(() => {
  dataHandlingWorker.postMessage(searchQuery);
}, [searchQuery]);

useEffect(() => {
  dataHandlingWorker.onmessage = (m) => {
    setBooksList(m.data);
  };
}, []);

【问题讨论】:

  • 你的代码在哪里?
  • 您链接的问题似乎与您的“Failed to parse URL”错误无关?
  • 尝试使用绝对网址

标签: javascript web-worker


【解决方案1】:

blob:// URI 创建的工作人员有自己的baseURI set to set to that blob:// URI

要获取相对 URL,浏览器首先必须从当前领域的 baseURI 构建绝对 URI。

因此,在您的情况下,浏览器将尝试使用 blob:[origin]/[UUID] 作为基础从 /api/books 生成绝对 URL。 这就是抛出

const worker_script = `
  postMessage( { baseURI: self.location.href } );
  try {
    const absolute = new URL( "api/books", self.location.href );
  }
  catch( err ) {
    postMessage( { err: err.toString() } );
  }
`;
const worker_url = URL.createObjectURL( new Blob( [ worker_script ] ) );
const worker = new Worker( worker_url );
worker.onmessage = (evt) => console.log( evt.data );

要解决该问题,您有两种选择:

  • 使用绝对 URL。这样你就不会遇到这个问题了。

  • baseURI 从您的主线程传递到您的 Worker 脚本。这样您就可以使用URL constructor 自己创建绝对 URL。

第一个选项非常简单,所以我想您不需要示例。 其次,由于我们无法在 StackSnippets 中托管相关文件,I had to host it in this plunker

代码如下:

const worker_script = `
  onmessage = (evt) => {
    const base = evt.data;
    const absolute = new URL( "api/books", base );
    fetch( absolute )
      .then( (resp) => resp.text() )
      .then( (txt) => postMessage( txt ) )
      .catch( console.error );
  };
`;
const worker_url = URL.createObjectURL( new Blob( [ worker_script ] ) );
const worker = new Worker( worker_url );
worker.onmessage = (evt) => document.body.append( evt.data );
// pass the main thread's baseURI
worker.postMessage( document.baseURI );

【讨论】:

    【解决方案2】:

    我的问题是我想根据缓存做出有条件的响应。

    我在使用请求对象并关注这篇文章并使用绝对url解决了问题。

    const respuesta = caches.match('codeGalery/cat.jpg')
    .then((response) => 
    {
      if (response !== undefined)
      {
        return response;
      }
      //wrong
      //return fetch(FetchEvent.request, {credentials:"same-origin"});
      //correct
      return fetch(FetchEvent.request.url, {credentials:"same-origin"});
    
    });
    

    【讨论】:

      猜你喜欢
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-17
      • 2021-05-17
      • 2022-11-06
      • 1970-01-01
      • 2019-01-07
      相关资源
      最近更新 更多