0

In background.js, my browser extension periodically fetches a JSON file published in a GitHub public repository.

Now I want it to be nicer to GitHub and its bandwidth limits, and only fetch file again if it was modified since last update:

url='https://raw.githubusercontent.com/LearnWebCode/json-example/master/pets-data.json';

fetch(url, {
  headers: {'If-Modified-Since': 'Wed, 15 Aug 2022 18:30:00 GMT'}})
.then(response => response.json())
.then(json => console.log('Loaded: ', json));

However I get CORS error I don't understand how to deal with:

Access to fetch at
'https://raw.githubusercontent.com/LearnWebCode/json-example/master/pets-data.json'
from origin 'chrome-extension://...'
has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
It does not have HTTP ok status.

Adding either combination of other headers doesn't make difference:

 'Content-Type': 'text/plain;charset=UTF-8'
 'Accept': 'application/vnd.github.v3.raw'
 'User-Agent': 'my_github_username/my_github_repository (Chrome 104.0.5112.79)'

Neither does using GitHub Pages as an alternative way to access the file.


Update: I easily eliminated CORS error adding raw.githubusercontent.com to host_permissions in manifest.json (thanks @wOxxOm). However now If-Modified-Since doesn't seem to be affect server behavior in the way I expect, see followup question with details.

wass rubleff
  • 326
  • 1
  • 14
  • You need to add `https://raw.githubusercontent.com/` to [host_permissions in manifest.json](https://developer.chrome.com/docs/extensions/mv3/xhr/#requesting-permission). – wOxxOm Aug 16 '22 at 06:06
  • @wOxxOm Thanks, it really helped! Now I don't have that error message, but If-Modified-Since doesn't seem to affect GitHub behavior in any way: https://stackoverflow.com/q/73379755 – wass rubleff Aug 16 '22 at 20:08

1 Answers1

4

Because your request contains an If-Modified-Since header, the browser triggers CORS preflight. However, the resource, despite responding to GET requests with Access-Control-Allow-Origin: *, doesn't seem to support preflight: if you try to spoof a preflight request, it invariably (according to my tests) replies with a 403 status, which is sufficient for CORS preflight to fail.

The resource does respond with an ETag header. One approach would consist in sending a simple HEAD request first, read the value of the response's ETag header, and conditionally send a GET request after that. Unfortunately, because ETag is not a CORS-safelisted response-header name and the response doesn't contain any Access-Control-Expose-Headers header, the browser won't expose the response's ETag header to JavaScript. Very sad.

Short of pressuring GitHub into adding support for CORS preflight on https://raw.githubusercontent.com, a viable, albeit annoying, alternative would be to proxy your original GET request (containing the If-Modified-Since header) to a server you control, which would be unconstrained by the Same-Origin Policy.

jub0bs
  • 60,866
  • 25
  • 183
  • 186