Reputation: 1639
Yes. this is a complex question. i will try to nake it brief.
My website fetches resources from s3. I also have an extension that needs to prefetch that s3 file when someone does a google query, so later when they go on my site ,the resource is cached. At this point I should probably stress that I'm not doing anything malicious. just a matter of user experience. My problem is. that making an ajax request to s3 fron the extension (either from content-script or background) doesn't send an origin header. This means that the resource is downloaded and cached without an allow origin header. s3 doesnt add that allow-origin:* if theres no origin in the request. so later, on my site it fails due to missing allow-origin header in cached file :-(
Any ideas on a better way to prefetch to browser cache?
Is there a way to force the ajax request to send an origin? Any origin? Since I have an allow-origin:* on my s3 bucket, I think any origin will do accept null. Thanks
Edit: Ended up using one of Rob W's solutions. You are awesome. Let me comment on each of the options he suggested:
Not to add the host premissions on my manifest - clever idea but wouldn't work for me since I have a content script which runs on any website, so I must use a catch-all wildcard, and I don't think there is an "exclude" permission option.
I tried it, it issues a null origin, which as expected ends up in S3 sending the allow-origin:* header as required. this means I don't get that "allow-origin header missing" error, however the file is then not served from cache. I guess for it to be actually served from cache in chrome this has to be exactly the same origin. so that was very close but not enough.
third option is a charm. And it is the simplest. I didn't know I was able to manipulate the origin header. So I do that and set the exact origin of my website - And it works. The file is cached and later served from cache. I must stress that i had to add a Url filter to only apply this to requests going out to my s3 bucket, otherwise I expect this would wreak havoc on the user's browser.
Thanks. Well done
Upvotes: 0
Views: 1256
Reputation: 349192
You've got three options:
Origin
request header will be sent with the request.Use a non-extension frame to perform the AJAX request. For example, the following method will result in a cross-origin GET request with Origin: null
.
function prefetchWithOrigin(url) {
var html = '<script>(' + function(url) {
var x = new XMLHttpRequest();
x.open('GET', url);
x.onloadend = function() {
parent.postMessage('done', '*');
};
x.send();
} + ')(' + JSON.stringify(url) + ');</script>';
var f = document.createElement('iframe');
f.src = 'data:text/html,' + encodeURIComponent(html);
(document.body || document.documentElement).appendChild(f);
window.addEventListener('message', function listener(event) {
// Remove frame upon completion
if (event.source === f.contentWindow) {
window.removeEventListener('message', listener);
f.remove();
}
});
}
chrome.webRequest.onBeforeSendHeaders
event to manually append the Origin header.Upvotes: 1