HTTP request from Angular sent as OPTIONS instead of POST

前端 未结 5 675
孤街浪徒
孤街浪徒 2020-12-03 04:59

I\'m trying to send some HTTP requests from my angular.js application to my server, but I need to solve some CORS errors.

The HTTP request is made using the followin

相关标签:
5条回答
  • 2020-12-03 05:16

    The best is to

    1. have proxy.conf.json set:
        {
          "/api": {
            "target": "http://localhost:8080",
            "secure": false,
            "logLevel": "debug",
            "changeOrigin": true
          }
        } 
    
    1. And then to make sure that URL that you are using in angular to send a request is relative (/api/something) and not absolute (localhost:8080/api/something). Because in that case the proxy won't work.

    Good luck!

    0 讨论(0)
  • 2020-12-03 05:20

    I ran into a very similar problem writing an Angular 2 app - that uses a NODE server for the API.

    Since I am developing on my local machine, I kept getting Cross Origin Header problems, when I would try to POST to the API from my Angular app.

    Setting the Headers (in the node server) as below worked for GET requests, but my PUT requests kept posting empty objects to the database.

    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
    header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, 
    Origin, Authorization, Accept, Client-Security-Token, Accept-
    Encoding, X-Auth-Token, content-type');
    

    After reading Dawid Ferenczy's post, I realized that the PREFLIGHT request was sending blank data to my server, and that's why my DB entries were empty, so I added this line in the NODE JS server:

      if (req.method == "OPTIONS")
        {
            res.writeHead(200, {"Content-Type": "application/json"});
            res.end();
        }
    

    So now my server ignores the PREFLIGHT request, (and returns status 200, to let the browser know everything is groovy...) and that way, the real request can go through and I get real data posted to my DB!

    0 讨论(0)
  • 2020-12-03 05:20

    Just put

    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    header("HTTP/1.1 200 ");
    exit;}
    

    at the beginning of your serverside app and you should be fine.

    0 讨论(0)
  • 2020-12-03 05:35

    The OPTIONS request is so called pre-flight request, which is part of Cross-origin resource sharing (CORS). Browsers use it to check if a request is allowed from a particular domain as follows:

    1. The browser wants to send a request, let's say a POST request with the application/json content type
    2. So first, it sends the pre-flight OPTIONS request
    3. If the server replies with a non-2XX status response, the browser won't send the actual request (because he knows now that it would be refused anyway)
    4. If the browser got a HTTP 200 OK response to the pre-flight request, it sends the actual request, POST in your case

    Theory

    Simple requests

    Browsers are not sending the pre-flight requests in some cases, those are so-called simple requests and are used in the following conditions:

    • One of the allowed methods:
      • GET
      • HEAD
      • POST
    • Apart from the headers automatically set by the user agent (for example, Connection, User-Agent, etc.), the only headers which are allowed to be manually set are the following:
      • Accept
      • Accept-Language
      • Content-Language
      • Content-Type (but note the additional requirements below)
      • DPR
      • Downlink
      • Save-Data
      • Viewport-Width
      • Width
    • The only allowed values for the Content-Type header are:
      • application/x-www-form-urlencoded
      • multipart/form-data
      • text/plain
    • No event listeners are registered on any XMLHttpRequestUpload object used in the request; these are accessed using the XMLHttpRequest.upload property.
    • No ReadableStream object is used in the request.

    Such requests are sent directly and the server simply successfully processes the request or replies with an error in case it didn't match the CORS rules. In any case, the response will contain the CORS headers Access-Control-Allow-*.

    Pre-flighted requests

    Browsers are sending the pre-flight requests if the actual request doesn't meet the simple request conditions, the most usually:

    • custom content types like application/xml or application/json, etc., are used
    • the request method is other than GET, HEAD or POST
    • the POST method is of an another content type than application/x-www-form-urlencoded, multipart/form-data or text/plain

    You need to make sure that the response to the pre-flight request has the following attributes:

    • successful HTTP status code, i.e. 200 OK
    • header Access-Control-Allow-Origin: * (a wildcard * allows a request from any domain, you can use any specific domain to restrict the access here of course)

    From the other side, the server may refuse the CORS request simply by sending a response to the pre-flight request with the following attributes:

    • non-success HTTP code (i.e. other than 2XX)
    • success HTTP code (e.g. 200 OK), but without any CORS header (i.e. Access-Control-Allow-*)

    See the documentation on Mozilla Developer Network or for example HTML5Rocks' CORS tutorial for details.


    TL;DR answer

    So, in your case, the proper header is present, you just have to make sure the pre-flight response's HTTP status code is 200 OK or some other successful one (2XX).

    0 讨论(0)
  • 2020-12-03 05:35

    For spring boot application, to enable cors request, use @CrossOrigin(origins = "*", maxAge = 3600) on your respective controller.

    Refer this doc

    0 讨论(0)
提交回复
热议问题