129-跨域(一)ajax跨域訪問、解決跨域后session失效問題

1. ajax跨域

在Web編程中我們經(jīng)常會(huì)遇到跨域的問題。默認(rèn)情況下,瀏覽器是不允許跨域訪問的。所以說,在這里就有一個(gè)概念:CORS(Cross-Origin Resource Sharing)跨域資源共享。

在HTML5標(biāo)準(zhǔn)出來之前,CORS是不被允許的。但是為了達(dá)到跨域訪問資源的目的,出現(xiàn)了很多較麻煩的方式:jsonp、代理文件、地址欄hash等等。隨著HTML5的出現(xiàn),CORS為我們解決了一個(gè)大麻煩。

雖然前端有多種方式處理跨域,但是多而不精,缺點(diǎn)都比較明顯.相對(duì)而言更好的方式是通過后端參與處理,這樣做不僅適用性更強(qiáng),同時(shí)前端只要發(fā)送正常的Ajax請(qǐng)求即可.這樣的技術(shù)叫做CORS.

Nodejs服務(wù)器端:

要想實(shí)現(xiàn)跨域訪問,首先我們要清楚CORS實(shí)現(xiàn)跨域訪問最重要的一點(diǎn)就是設(shè)置Access-Control-Allow-Origin這個(gè)參數(shù)。

var express = require('express');
var app = express();
//設(shè)置跨域訪問
app.all('*', function(req, res, next) {
    //設(shè)置全局訪問,這里的*將到替換成你的域名
    res.setHeader('Access-Control-Allow-Origin', '*');
    //告訴客戶端可以接受請(qǐng)求的方式
    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ù)端即可,在客戶端不用進(jìn)行其他的設(shè)置就可以實(shí)現(xiàn)跨域訪問了。


上面的設(shè)置僅僅是可以跨域訪問,但對(duì)于設(shè)置cookie還是不能跨域設(shè)置和讀取。(服務(wù)器端生成session后會(huì)設(shè)置給客戶端的cookie中)
接下來我們就來進(jìn)行cookie跨域的設(shè)置。

2. 解決ajax跨域后session失效問題

  • 客戶端如下:

ajax請(qǐng)求添加參數(shù):
//ajax請(qǐng)求攜帶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請(qǐng)求中帶上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請(qǐng)求中帶上Cookie
    res.setHeader('Access-Control-Allow-Credentials', true);
    //告訴客戶端可以接受請(qǐng)求的方式
    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 : '手機(jī)號(hào)碼不能為空'})+')');
      return false;
    }

    //手機(jī)驗(yàn)證碼正確
    user.find({phone:phone}, function(err, result){
      if(err){
        console.log(err);
        res.send(jsonpcallback+'('+JSON.stringify({state:'err', msg : '服務(wù)器繁忙,請(qǐng)稍后再試!'})+')');
        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ù)
      
      //密碼錯(cuò)誤
      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 : '登錄成功'})+')');
    });
  },
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容