刚刚接触backbone.js 和 node.js 做跨域处理的时候困扰了我好几天,通过差各种资料终于解决了,但是基本上都是英文的,而且没有完整的一个资料介绍node和backbone的设置,所以发表篇中文的,共咱国人参考!
因为刚接触不久,以前是写C++服务器的,从来没接触过webserver,所以可能有很多地方说的不深刻,望见谅!如有错误处还请指出,共同探讨!
首先服务端要允许跨域
node.js express 服务端设置:
利用express的中间件
var allowCrossDomain = function(req, res, next) {// if the origin was not passed.var origin = (req.headers.origin || "*");console.log('origin:' + origin);res.header('Access-Control-Allow-Credentials', true);res.header('Access-Control-Allow-Origin', origin);res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');res.header('Access-Control-Allow-Headers', 'Set-Cookie, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version');if ("OPTIONS" == req.method) {res.send(200);} else {next();}};app.use(allowCrossDomain);
注意一定要在app.use(app.router);之前!
简单解释一下
res.header('Access-Control-Allow-Credentials', true); //允许客户端发送cookie信息res.header('Access-Control-Allow-Origin', origin); //origin为客户端自己的域名,如果不是跨域为'*'res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); //允许客户端发送的请求方法
cors跨域请求首先会发送一个OPTIONS给服务端,直接返回200就可以
backbone.js 客户端设置:
backbone.js的通信是基于jquery的,所以先看看jquery应该怎么样设置:
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {options.crossDomain ={crossDomain: true};options.xhrFields = {withCredentials: true};});crossDomain: true // 允许跨域withCredentials: true //允许发送cookie数据给服务器,默认为false
设置了这俩项通信就应该没有问题了!
那么看看backbone.js应该怎么设置:
(function() {var proxiedSync = Backbone.sync;Backbone.sync = function(method, model, options) {options || (options = {});if (!options.crossDomain) {options.crossDomain = true;}if (!options.xhrFields) {options.xhrFields = {withCredentials:true};}return proxiedSync(method, model, options);};})();
当backbone.js有通信的时候会事先调用Backbone.sync函数,我们重载这个函数把crossDomain、withCredentials设置上就ok了!
在通常写backbone.js客户端的时候通常会直接利用jquery的ajax进行通信,比如post登陆信息等,下面举个简单登陆的例子:
$.ajax({type: 'post',crossDomain: true,url: '/admin/login',data: {UserName: $('#name:text', this.el).val(),PassWord: $('#Password:password', this.el).val()},dataType:'json',xhrFields: {withCredentials: true},success: function(data, textStatus, jqXHR){console.log("getAllResponseHeaders:"+jqXHR.getAllResponseHeaders());console.dir(jqXHR);Backbone.history.navigate("#booklist",true);}});
主要还是设置下crossDomain和withCredentials属性。这样基本上就ok了!
另外,客户端和服务端的domain最好是在一个domain下,这样cookie才能保证没问题。
node.js服务端设置方法:
一、首先在中间件上设置
app.use(express.session({ secret: config.session_secret, cookie: { domain: '.'} }));
二、在生成cookie时设置
res.cookie(config.auth_cookie_name, auth_token, {domain: '.'});
可能设置其中一个就可以,但是我测试的时候总出现问题,不知道是不是别的地方影响的,所幸就都设置上了!
ok done!