129-跨域(一)ajax跨域访问、解决跨域后session失效问题

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 : '登录成功'})+')');
    });
  },
}

你可能感兴趣的:(129-跨域(一)ajax跨域访问、解决跨域后session失效问题)