1. ajax跨域
在Web編程中我們經(jīng)常會遇到跨域的問題。默認情況下疗疟,瀏覽器是不允許跨域訪問的该默。所以說,在這里就有一個概念:CORS(Cross-Origin Resource Sharing)跨域資源共享策彤。
在HTML5標準出來之前栓袖,CORS是不被允許的。但是為了達到跨域訪問資源的目的锅锨,出現(xiàn)了很多較麻煩的方式:jsonp叽赊、代理文件、地址欄hash等等必搞。隨著HTML5的出現(xiàn)必指,CORS為我們解決了一個大麻煩。
雖然前端有多種方式處理跨域,但是多而不精,缺點都比較明顯.相對而言更好的方式是通過后端參與處理,這樣做不僅適用性更強,同時前端只要發(fā)送正常的Ajax請求即可.這樣的技術(shù)叫做CORS.
Nodejs服務(wù)器端:
要想實現(xiàn)跨域訪問恕洲,首先我們要清楚CORS實現(xiàn)跨域訪問最重要的一點就是設(shè)置Access-Control-Allow-Origin這個參數(shù)塔橡。
var express = require('express');
var app = express();
//設(shè)置跨域訪問
app.all('*', function(req, res, next) {
//設(shè)置全局訪問,這里的*將到替換成你的域名
res.setHeader('Access-Control-Allow-Origin', '*');
//告訴客戶端可以接受請求的方式
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
next();
});
app.get('/auth/:id/:password', function(req, res) {
res.send({id:req.params.id, name: req.params.password});
});
app.listen(3000);
只需要設(shè)置服務(wù)端即可霜第,在客戶端不用進行其他的設(shè)置就可以實現(xiàn)跨域訪問了葛家。
上面的設(shè)置僅僅是可以跨域訪問,但對于設(shè)置cookie還是不能跨域設(shè)置和讀取泌类。(服務(wù)器端生成session后會設(shè)置給客戶端的cookie中)
接下來我們就來進行cookie跨域的設(shè)置癞谒。
2. 解決ajax跨域后session失效問題
- 客戶端如下:
ajax請求添加參數(shù):
//ajax請求攜帶cookie
xhrFields:{withCredentials:true},
//全局變量
var HOST = 'http://172.16.0.131:3000';
$.ajax({
url:HOST+'/login',
type:'get',
data:params,
xhrFields:{withCredentials:true},
dataType:'jsonp',
jsonp:'jsonpcallback',
success:function(data){
console.log(data);
...
},
error:function(){
...
}
});
- 服務(wù)器端
//告訴客戶端可以在HTTP請求中帶上Cookie
res.setHeader('Access-Control-Allow-Credentials', true);
路由文件route.json:
{
"/login" : "usercontroller#login",
}
公共comm.js文件內(nèi)容
//初始化設(shè)置
var initSet = function(req, res){
//設(shè)置全局訪問
res.setHeader('Access-Control-Allow-Origin', '*');
//告訴客戶端可以在HTTP請求中帶上Cookie
res.setHeader('Access-Control-Allow-Credentials', true);
//告訴客戶端可以接受請求的方式
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
return res;
}
usercontroller.js文件
//引入模塊
const comm = require('../models/comm');
const config = require('../config');
const user = require('../models/user.js');
const qs = require('querystring');
const url = require('url');
const fs = require('fs');
var session = require('express-session');
var crypto = require('crypto');
var multiparty = require('multiparty');
//引入 mime模塊
const mime = require('mime');
module.exports = {
//登錄
login : function(req, res){
//初始化設(shè)置
res = comm.initSet(req, res);
var params = url.parse(req.url,true).query;
var jsonpcallback = params.jsonpcallback;
var phone = params.phone;
var password = params.password;
if(phone == ""){
res.send(jsonpcallback+'('+JSON.stringify({state:'err', msg : '手機號碼不能為空'})+')');
return false;
}
//手機驗證碼正確
user.find({phone:phone}, function(err, result){
if(err){
console.log(err);
res.send(jsonpcallback+'('+JSON.stringify({state:'err', msg : '服務(wù)器繁忙,請稍后再試!'})+')');
return false;
}
//用戶不存在
if(result.length <= 0){
res.send(jsonpcallback+'('+JSON.stringify({state:'err', msg : '用戶不存在'})+')');
return false;
}
var hasher = crypto.createHash('md5');
hasher.update(password);
var newpassword = hasher.digest('hex');//hashmsg為加密之后的數(shù)據(jù)
//密碼錯誤
if(result[0].password != newpassword){
res.send(jsonpcallback+'('+JSON.stringify({state:'err', msg : '密碼不正確'})+')');
return false;
}
//存入session
req.session.uid = result[0]._id;
req.session.username = result[0].username;
req.session.phone = params.phone;
req.session.tag = 1;
console.log(req.session);
res.send(jsonpcallback+'('+JSON.stringify({state:'ok', msg : '登錄成功'})+')');
});
},
}