I'm experimenting with the Octoprint API and I'm running into a problem accessing the GCode file of the currently running print job. Authentication is disabled for development in Octoprint, and the "Allow Cross Origin Resource Sharing" setting in the API section is enabled.
I'm running Octoprint 1.3.10 on localhost:5000, and my own web application on localhost:8080. I can connect to the Octoprint push API via websocket and receive updates about the status of the printer without issues. But when I try to fetch the GCode file of the currently running print, I get the following error:
Access to fetch at 'http://localhost:5000/downloads/files/local/test_folder/test.gcode' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
It's a bit unclear to me how the "allow CORS" setting in Octoprint is supposed to work. I can access the websocket on an Octoprint instance with authentication disabled even when "allow CORS" is set to false. But I can't access GCode files even when "allow CORS" is enabled.
Which parts of the API is the CORS setting meant to cover? Are file downloads and websocket access meant to be affected by this setting?
And how can I configure Octoprint to set a permissive CORS policy for GCode file downloads, so that I can access them from my own web application?
Another factor would be if your requesting code is running within an HTTPS context and it's trying to pull something from an HTTP URL from OctoPrint. I'm kind of sure that CORS would fail in a situation like that since it feels like a "privacy demotion", so-to-speak for the end user.
Otherwise, you might take the advice in the error and set the Mode to 'no-cors'. Perhaps that's the fix.
Both, Octoprint and my own web application are running on plain http right now. I played around with this a bit more, and I can get this to work by starting Chrome with the --disable-web-security parameter. That's fine for local development, but obviously not usable in real use as it disabled some important security mechanisms entirely.
The "no-cors" option is meant for something like a proxy. It doesn't allow you to look inside the request, as that would defeat the CORS security mechanism entirely.
I might be missing some subtle point here, and this subject certainly is far from trivial, but I think that the CORS setting should apply to all requests, the REST API, any kind of download and any other category I don't know about.
I think you've come across a bug there which needs to be looked into. I remember putting the CORS request handlers around the actual API endpoints, but not around any of the static routes (e.g. the /downloads/ endpoint handled by Tornado instead of Flask). And the websocket needs some closer look as well from your description.