1. ajax跨域
在Web编程中我们经常会遇到跨域的问题。默认情况下,浏览器是不允许跨域访问的。所以说,在这里就有一个概念:CORS(Cross-Origin Resource Sharing)跨域资源共享。
在HTML5标准出来之前,CORS是不被允许的。但是为了达到跨域访问资源的目的,出现了很多较麻烦的方式:jsonp、代理文件、地址栏hash等等。随着HTML5的出现,CORS为我们解决了一个大麻烦。
虽然前端有多种方式处理跨域,但是多而不精,缺点都比较明显.相对而言更好的方式是通过后端参与处理,这样做不仅适用性更强,同时前端只要发送正常的Ajax请求即可.这样的技术叫做CORS.
Nodejs服务器端:
要想实现跨域访问,首先我们要清楚CORS实现跨域访问最重要的一点就是设置Access-Control-Allow-Origin这个参数。
var express = require('express');
var app = express();
//设置跨域访问
app.all('*', function(req, res, next) {
//设置全局访问,这里的*将到替换成你的域名
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);
只需要设置服务端即可,在客户端不用进行其他的设置就可以实现跨域访问了。
上面的设置仅仅是可以跨域访问,但对于设置cookie还是不能跨域设置和读取。(服务器端生成session后会设置给客户端的cookie中)
接下来我们就来进行cookie跨域的设置。
2. 解决ajax跨域后session失效问题
- 客户端如下:
ajax请求添加参数:
//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(){
...
}
});
- 服务器端
//告诉客户端可以在HTTP请求中带上Cookie
res.setHeader('Access-Control-Allow-Credentials', true);
路由文件route.json:
{
"/login" : "usercontroller#login",
}
公共comm.js文件内容
//初始化设置
var initSet = function(req, res){
//设置全局访问
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){
//初始化设置
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 : '服务器繁忙,请稍后再试!'})+')');
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为加密之后的数据
//密码错误
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 : '登录成功'})+')');
});
},
}