Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    CORS policy: No 'Access-Control-Allow-Origin'

    Scheduled Pinned Locked Moved
    Duet Web Control
    6
    13
    892
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • DDDundefined
      DDD
      last edited by DDD

      Hi,

      I'm working on a web controller for Duet. The web control software is hosted on the internet, and accessed via a PC. The PC is connected to the printer with Duet 3 6HC with the SBC set as an access point.

      When the printer and software start, it works like a charm. Connects, GET, and POST requests can be made. However, if reset is hit (on the DWC, M112 code or physically pushing the reset button), I receive the following error when trying to reconnect:

      Access to XMLHttpRequest at 'http://192.168.1.10/machine/connect?password=reprap' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
      

      It seems that no matter what we do on the server side, nothing works only after either, the printer has been turn off and on again, or the webserver has been restarted (sudo systemctl restart duetwebserver via SSH).

      This our httpRequest function, using AxiosRequest

      export async function httpRequest(config: IRequestConfig) {
          const fullUrl = `http://${PRINT_WEBSERVER}${config.url}`;
          console.log(`Request to ${fullUrl}`);
          const request: AxiosRequestConfig = {
              ...config,
              url: fullUrl,
          };
          try {
              const response = await axios(request);
               }
              console.log(`Success! - Request to ${fullUrl} returned`, response.data);
              return response;
          } catch (e: any) {
              console.log(`Failed! - Request to ${fullUrl} returned ${e.status} - ${e.message}`);
              throw e;
          }
      }
      

      How to connect to the printer again, after a reset or how can we reset the webserver via JS?

      dc42undefined hauschkaundefined 2 Replies Last reply Reply Quote 0
      • dc42undefined
        dc42 administrators @DDD
        last edited by

        @DDD see https://docs.duet3d.com/en/User_manual/Reference/Gcodes#m586-configure-network-protocols in particular the C parameter.

        Duet WiFi hardware designer and firmware engineer
        Please do not ask me for Duet support via PM or email, use the forum
        http://www.escher3d.com, https://miscsolutions.wordpress.com

        DDDundefined 1 Reply Last reply Reply Quote 0
        • DDDundefined
          DDD @dc42
          last edited by DDD

          @dc42 the config.g has it, and I created a dsf-config.g and added to it. Also, was manually executed via DWC after reset. Same results

          chrishammundefined 1 Reply Last reply Reply Quote 0
          • Phaedruxundefined
            Phaedrux Moderator
            last edited by

            Firmware version?

            Z-Bot CoreXY Build | Thingiverse Profile

            1 Reply Last reply Reply Quote 0
            • chrishammundefined
              chrishamm administrators @DDD
              last edited by

              @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.

              Duet software engineer

              DDDundefined 1 Reply Last reply Reply Quote 0
              • DDDundefined
                DDD @chrishamm
                last edited by

                @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.

                Phaedruxundefined 1 Reply Last reply Reply Quote 0
                • Phaedruxundefined
                  Phaedrux Moderator @DDD
                  last edited by

                  @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.5

                  Your 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.

                  Z-Bot CoreXY Build | Thingiverse Profile

                  1 Reply Last reply Reply Quote 0
                  • hauschkaundefined
                    hauschka @DDD
                    last edited by

                    @DDD

                    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.

                    chrishammundefined 1 Reply Last reply Reply Quote 0
                    • chrishammundefined
                      chrishamm administrators @hauschka
                      last edited by

                      @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 my dsf-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.

                      Duet software engineer

                      hauschkaundefined 1 Reply Last reply Reply Quote 0
                      • hauschkaundefined
                        hauschka @chrishamm
                        last edited by

                        @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!

                        45d625a9-e124-4a57-802e-557646840e8b-grafik.png

                        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.

                        dainonundefined 1 Reply Last reply Reply Quote 0
                        • dainonundefined
                          dainon @hauschka
                          last edited by dainon

                          @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.

                          hauschkaundefined 1 Reply Last reply Reply Quote 0
                          • hauschkaundefined
                            hauschka @dainon
                            last edited by

                            @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

                            dainonundefined 1 Reply Last reply Reply Quote 0
                            • dainonundefined
                              dainon @hauschka
                              last edited by dainon

                              @hauschka

                              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?

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post
                              Unless otherwise noted, all forum content is licensed under CC-BY-SA