AngularJS $resource makes HTTP OPTIONS request instead of HTTP POST for $save method

后端 未结 2 1583
感情败类
感情败类 2020-12-25 12:57

I\'m in the process of writing a simple library application to get ready for a larger project with AngularJS. After reading a lot online about using $resource t

相关标签:
2条回答
  • 2020-12-25 13:00

    I know it may be in bad taste to answer my own question but I figured out the problem a few days after posting this.

    It all comes down to how browsers manage CORS. When making a cross-domain request in JavaScript that is not "simple" (i.e. a GET request - which explains why the query() function worked), the browser will automatically make a HTTP OPTIONS request to the specified URL/URI, called a "pre-flight" request or "promise". As long as the remote source returns a HTTP status code of 200 and relevant details about what it will accept in the response headers, then the browser will go ahead with the original JavaScript call.

    Here's a brief jQuery example:

    function makeRequest() {
        // browser makes HTTP OPTIONS request to www.myotherwebsite.com/api/test
        // and if it receives a HTTP status code of 200 and relevant details about
        // what it will accept in HTTP headers, then it will make this POST request...
        $.post( "www.myotherwebsite.com/api/test", function(data) {
            alert(data);
        });
        // ...if not then it won't - it's that simple.
    }
    

    All I had to do was add the details of what the server will accept in the response headers:

    // apply this rule to all requests accessing any URL/URI
    app.all('*', function(req, res, next) {
        // add details of what is allowed in HTTP request headers to the response headers
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
        res.header('Access-Control-Allow-Credentials', false);
        res.header('Access-Control-Max-Age', '86400');
        res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
        // the next() function continues execution and will move onto the requested URL/URI
        next();
    });
    

    And then insert these few lines before the Express routing to simply return a HTTP 200 status code for every OPTIONS request:

    // fulfils pre-flight/promise request
    app.options('*', function(req, res) {
        res.send(200);
    });
    

    Hopefully this will help anyone who stumbles on this page suffering from the same problem.

    0 讨论(0)
  • 2020-12-25 13:05

    I didn´t actually try this, but wouldn´t it be enough to tell the Ressource how to handle the $save request?

    $resource('http://mywebserver\\:1337/books/:bookId', { bookId: '@bookId' }, {save: {method: 'POST'});
    
    0 讨论(0)
提交回复
热议问题