CORS policy: No 'Access-Control-Allow-Origin'
-
Firmware version?
-
@DDD Please make sure you're running the latest version 3.4.5 (or newer). What does your M586 command look like? You need to restart the machine and/or DSF (e.g. by pressing E-STOP) to apply the new CORS value.
-
@chrishamm @Phaedrux
Duet Web Control 3.4.1
DSF Version: 3.4.1
RepRapFirmware for Duet 3 MB6HC 3.4.5
On config.g - M586 C"*"Making further tests, our emergency button sends M112 M999. If I send only the M112 command, the websocket keeps working. Sending M999 creates the error. If I press the emergency button on DWC or the physical button connected to the reset pins, the websocket cannot connect back until the duet web server is reset or power cycle the machine.
-
@DDD said in CORS policy: No 'Access-Control-Allow-Origin':
Duet Web Control 3.4.1
DSF Version: 3.4.1
RepRapFirmware for Duet 3 MB6HC 3.4.5Your firmware version is ahead of DSF and DWC. They need to match. Please run sudo apt update and sudo apt upgrade and check versions again.
-
Hi,
I'm running into the same error with a custom web-based app to control my printer.
I initiate the connection through the websocket and it works.
Whenever I send reset (M112 + M999), the webapp cannot initiate the connection anymore, giving me a network error.Is there a description somewhere on how the traffic to the websocket must be structured?
I checked the implementation on the Duet side: https://github.com/Duet3D/DuetWebControl/blob/e9c241a72a68c425d0983b4b819e480817f4871e/src/store/machine/connector/RestConnector.js
Do you need to store a sessionkey? when does it refresh? do you need to send it in the header?
could that be the reason you are getting a CORS message?@chrishamm could you please shine some line on the required communication logic for the Duet websocket to reconnect after reset? How is this solved on the DWC?
(or does it not trigger CORS because it's the same host?)
I already set UseCorse to false in the config file and set M586 C"*" .What am I missing?
Any help is appreciated. -
@hauschka It's all documented here: https://github.com/Duet3D/DuetSoftwareFramework/wiki/REST-API-(v3.4.4-or-newer). The session key is independent from CORS, CORS is just a security feature to prevent cross-domain access. That's why you need to disable it for HTTP development on your local PC.
I have
M586 C"*"
in mydsf-config.g
which is executed whenever DCS starts up (or more precisely when the plugin services have started). Do you execute it on start-up as well (either via config.g or dsf-config.g)? The M586 value is automatically reset whenever you restart the Duet via M999. -
@chrishamm
thanks chris for linking the docs, I must have missed them.I can now disconnect and connect to previous sessions by storing the sessionkey.
However, as soon as I reset the printer (M112, M999) and I try to reconnect to the websocket again, I get a CORS error
The config.g, as well as the dsf-config.g both have M586 C"*" as the first line.
Funnily enough, if I'm fast enough, right after hitting reset, I disconnect and re-connect directly, then I can re-initiate the websocket, but not send any commands, as all GET requests result in a CORS error!
Is there a different way of disabling the CORS headers?
Or a different way of dealing with this kind of behaviour?
I spent the past 10 hours trying to circumvent this problem to no avail. -
@hauschka
I ran into this issue while creating my own web interface for the Duet3 6HC.Instead of dealing with the headaches of CORS, which I've done for projects at work, I bypassed the CORS errors by using the same domain name, and relaying the REST calls on the server side. I wrote it up in the CNC forum if it's of any use to you. I have both REST and WS working this way with no issues.
https://forum.duet3d.com/topic/31844/readdressing-the-cnc-gui-thoughts
Basically use Nginx as the domain proxy redirect and the new website with different paths. As this is only an issue with REST, your WebSockets will work just fine as CORS doesn't apply to the WS/WSS protocol. I posted the nginx config and REST relay file over in CNC.
-
@dainon
Thanks for the write-up, that's an interesting solution.
Can you tell me how exactly a reverse proxy circumvents the CORS issue?
How exactly does the relaying part work?At the moment, our website is hosted on a domain, in our case with an ingress tunnel from cloudflare.
The thing is.... I'm not even sure what is causing the CORS, as I AM connecting to the device from the same location (ie origin) after reset.
I'm trying to understand where the error stems from and how your implementation is different?@chrishamm is there a way to completely disable CORS on the RPi, without gcode? Is it possible to change in the server code?
There used to be a way to hard-code it by editing UseCors in /opt/dsf/conf/http.json from false to true.
I also tried that to no avail.
Is there a different way to change the server headers?On a related basis, where do I find the logs of these CORS events server-side?
Perhaps this can help debugging the issue further?Thank you everyone for the feedback!
Best,
-h -
Can you tell me how exactly a reverse proxy circumvents the CORS issue?
CORS, which is a security feature, is upheld by the browser to maintain that a client is requesting the resources from the same origin. In the case of writing your own website for Duet you now have 2 origins: (A) Duet3D Web Server, (B) Your Custom Web Server. Each of these is it's own origin. As a client using (B), you request pages/content from (B) which becomes B-Client in this example. Your code on the client side sends requests to from B-Client to A, which is Cross-Origin Resource Sharing (CORS). This CORS error is the default and both the client and server have to explicitly state 'no-cors' in their HTTP/HTTPS headers. When you disable CORS from the client request, you've found it doesn't work either. To me, this is more headache than it's worth even when you control all the code, because CORS pops-up when you think you've solved it For that last time! in an OPTIONS packet you didn't explicitly send (i.e., like a WS/WSS upgrade packet).
Answer: Because, like you I was frustrated for many hours with CORS, I've shown two solutions to the same problem and not explained it very well. 1) The reverse-proxy makes it to where A and B are the same origin and your B-Client can talk to A and A doesn't know the difference. 2) If you cannot do this, you can relay the REST call from your server. For example: B-Client sends a REST call to B, then B sends a REST call to A, A responds to B, then B responds back to B-Client. This works because the CORs checks are enforced by the client browser, and the server side just says which origins are allowed (kind of stupid if you ask me, and you can test this using a API design tool like Postman or Insomnia). I just tested both Nginx and Server-side REST relay independently in my code to make sure I'm not blowing smoke, and I'm not.
The thing is.... I'm not even sure what is causing the CORS, as I AM connecting to the device from the same location (ie origin) after reset.
I'm trying to understand where the error stems from and how your implementation is different?
When you say same location, what specifically are your referring to: IP-Address, domain name, sub-domain, etc?