微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

node.js – AngularJS $资源使用HTTP OPTIONS请求而不是HTTP POST用于$save方法

我正在编写一个简单的图书馆应用程序,为AngularJS准备一个更大的项目。在网上阅读了很多关于使用$资源与RESTful API进行交互的资料之后,我决定可能会为实现它而提供一些节省时间和扩展的好处,而不是为每个请求使用$ http。问题是,由于某些原因(我不是CORS的专家,并且请求正在发送跨域)当使用$ save方法时,我的Node.js控制台显示

OPTIONS /books 200 1ms - 161b

使用query()方法工作正常 – Node控制台显示

GET /books 200 1ms - 228b

在这一点上,我已经停了几个小时,尝试下面的变体,但是它总是以$ save方式而不是POST(根据Angular文档应该是一个OPTIONS)请求。

AngularJS Web应用程序

app.js

var libraryApp = angular.module('libraryApp',['ngResource','ngRoute','libraryControllers']);

libraryApp.factory('$book',['$resource',function ($resource) {

    return $resource('http://mywebserver\\:1337/books/:bookId',{ bookId: '@bookId' });
}]);

controllers.js

var libraryControllers = angular.module('libraryControllers',[]);

libraryControllers.controller('BookCtrl',['$scope','$book',function($scope,$book) {

    ...

    $scope.addBook = function () {
        var b = new $book;
        b.isbn = "TEST";
        b.description = "TEST";
        b.price = 9.99;
        b.$save();
    };
}]);

具有Express REST API的Node.js

app.js

var express = require('express'),books = require('./routes/books'),http = require('http'),path = require('path');

var app = express();

...

// enable cross-domain scripting
app.all('*',function(req,res,next) {
    res.header("Access-Control-Allow-Origin",req.headers.origin);
    res.header("Access-Control-Allow-Headers","X-Requested-With");
    next();
});

// routing
app.get('/books',books.getAll);
app.get('/books/:isbn',books.get);
// This is what I want to fire with the $save method
app.post('/books',books.add);

http.createServer(app).listen(app.get('port'),function(){
    console.log('Express server listening on port ' + app.get('port'));
});

./routes/books.js

...

exports.add = function(req,res) {

    console.log("POST request received...");
    console.log(req.body.isbn);
};

尝试将此行放在我的配置功能删除$ httpProvider.defaults.headers.common [“X-Requested-With”];但没有变化。

我不是Angular / Node pro,但现在我认为这是与跨域有关,像我说的,我不是CORS的专家。

提前致谢。

解决方法

我知道回答我自己的问题可能是不好的味道,但我发布了这几天后才发现了这个问题。

这一切都归功于浏览器如何管理CORS。当以不是“简单”的JavaScript进行跨域请求(即GET请求 – 这就是为什么查询()函数工作的原因)时,浏览器将自动对指定的URL / URI进行HTTP OPTIONS请求,称为“飞行前”请求或“承诺”。只要远程源程序返回HTTP状态代码为200,以及有关响应标头中将接受的相关详细信息,则浏览器将继续执行原始JavaScript调用

这是一个简单的jQuery示例:

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

我只需要添加服务器将在响应标头中接受的细节:

// apply this rule to all requests accessing any URL/URI
app.all('*',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();
});

然后在Express路由之前插入几行,以便为每个OPTIONS请求简单地返回HTTP 200状态代码

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

希望这将帮助任何人绊倒在这页面上遇到同样的问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐