admin管理员组文章数量:1357312
I trying to fetch data from the server inside of a web worker. But in dev tools every time I got the same error.
Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'WorkerGlobalScope': Failed to parse URL from /api/books
I saw this answer about service workers, but it's not working for me.
WebWorker file code!
// 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;
Imported in React ponent.
import data_handling_worker from "./data-handling.web-worker";
const dataHandlingWorker = new Worker(data_handling_worker);
Running and posting messages inside of the hooks!
const [searchQuery, setSearchQuery] = useState('');
const [booksList, setBooksList] = useState([]);
useEffect(() => {
dataHandlingWorker.postMessage(searchQuery);
}, [searchQuery]);
useEffect(() => {
dataHandlingWorker.onmessage = (m) => {
setBooksList(m.data);
};
}, []);
I trying to fetch data from the server inside of a web worker. But in dev tools every time I got the same error.
Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'WorkerGlobalScope': Failed to parse URL from /api/books
I saw this answer about service workers, but it's not working for me.
WebWorker file code!
// 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;
Imported in React ponent.
import data_handling_worker from "./data-handling.web-worker";
const dataHandlingWorker = new Worker(data_handling_worker);
Running and posting messages inside of the hooks!
const [searchQuery, setSearchQuery] = useState('');
const [booksList, setBooksList] = useState([]);
useEffect(() => {
dataHandlingWorker.postMessage(searchQuery);
}, [searchQuery]);
useEffect(() => {
dataHandlingWorker.onmessage = (m) => {
setBooksList(m.data);
};
}, []);
Share
Improve this question
edited Mar 24, 2020 at 23:20
Oleksii Sytar
asked Mar 24, 2020 at 17:38
Oleksii SytarOleksii Sytar
3731 gold badge5 silver badges17 bronze badges
3
- Where is your code? – MonteCristo Commented Mar 24, 2020 at 17:59
- The question you linked doesn't seem to have anything to do with your "Failed to parse URL" error? – Bergi Commented Mar 24, 2020 at 18:02
- 3 Try using an absolute URL – Bergi Commented Mar 24, 2020 at 18:02
3 Answers
Reset to default 7Workers created from a blob://
URI have their baseURI
set to set to that blob://
URI.
To fetch a relative URL the browser first has to build an absolute URI from the current realm's baseURI
.
So in your case, the browser will try to generate an absolute URL from /api/books
using blob:[origin]/[UUID]
as the base. This is what throws:
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 );
To workaround that issue you have two options:
Use an absolute URL. This way you won't face that problem.
Pass the
baseURI
from your main thread to your Worker's script. This way you will be able to create the absolute URL yourself using the URL constructor.
The first option is really simple, so I guess you don't need an example. For the second, since we can't host relative files in StackSnippets, I had to host it in this plunker.
Here is the code:
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 );
My problem was that I wanted to make a conditional response depending on the cache.
I was using the request object and paying attention to this post and using the absolute url solved the problem.
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"});
});
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 );
本文标签:
版权声明:本文标题:javascript - Failed to execute 'fetch' on 'WorkerGlobalScope' - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743958889a2568650.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论