天天看點

徹底解決axios跨域,axios每次請求session都在不停變化的問題

我在開發過程中遇到這兩個問題,找了很多貼子但是都沒解決我的問題.

一個偶然,讓我走出困境,

問題

  • axios跨域請求
  • axios每次請求session都在不停變化

解決辦法

  • axios使用代理服務解決跨域
  • axios+vue請求時攜帶cookie,來解決axios每次請求session都不停變化

axios跨域

封裝axios為http.js,将http.js在main.js

徹底解決axios跨域,axios每次請求session都在不停變化的問題
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
// import store from '@/store'
// import { getToken } from '@/utils/auth'



// 建立一個獨立的axios執行個體
const http = axios.create({
  // baseURL: '', // url = base url + request url
  // // withCredentials: true, // send cookies when cross-domain requests
  // // request timeout
  // timeout: 7000,
  // 為了攜帶cookie保持session的唯一性
  withCredentials: true,
  // crossDomain: true
  baseURL: '', // 通過/api别名指定後端路由,這裡什麼都不要寫
  timeout: 5000,
  headers:{},
  // 不知道有什麼用
  // crossDomain:true
})

// 添加請求攔截器
axios.interceptors.request.use(
  function(config) {
    // do......
    console.log('請求攔截1')
    // 判斷token是否存在,并且設定接口白名單
    // Message({
    //   message: '正在發送請求',
    //   type: "success"
    // })
    // 在發送請求之前進行操作
    return config
  },
  function(error) {
    // do......
    console.log('請求攔截2')
    // 對請求錯誤進行操作
    return Promise.reject(error)
  }
)

// 添加響應攔截器
axios.interceptors.response.use(
  function(response) {
    console.log('請求攔截3')
    const code = response.data.code;
    if(code !== 10000) {
      Message({
        message: `請求發送錯誤:${code} ${response.data.msg}`,
        type: 'error'
      })
    } else {
      Message({
        message: '請求成功',
        type: 'success'
      })
    }
    // 對響應資料進行操作
    return response
  },
  function(error) {
    Message({
      message: `請求發生錯誤:${error}`,
      type: 'error'
    })
    console.log('請求攔截4')
    // 對響應錯誤進行操作
    return Promise.reject(error)
  }
)

export default http

           

不友善封裝的情況加,或者在main.js中添加

// 意思是攜帶cookie資訊,保持session的一緻性
axios.defaults.withCredentials = true
           

跨域

一定一定要注意的是,修改後一定要重新開機項目,否則不生效!!!

vue.config.js檔案

devServer: {
	proxy: {
      '/api': {
        /*
        * 很好了解,就是将請求位址的首個/看成 http://127.0.0.1:3000/
        * 例如: 請求 http://localhost:3000/api/object/session 可寫成
        * axios({method: 'get',url: "/api/object/session",data: {},})
        * */
        target: 'http://127.0.0.1:3000/api/',// 後端接口
        changeOrigin: true, // 是否跨域
        // pathRewrite這個值完全可以不要
        pathRewrite: {
          //這裡了解成用‘/api’代替target裡面的位址,元件中我們調接口時直接用/api代替,完全是累贅
          '^/api': ''
        }
      }
    },
    port: port,
    // open: true,
    overlay: {
      warnings: false,
      errors: true
    }
  },
           

koa2後端

其他語言後端同理設定即可

/**
 * 解決跨域
 */

app.use(async (ctx, next) => {
	// 絕對不能使用 * ,使用 * 後無法擷取cookie
    ctx.set('Access-Control-Allow-Origin', ctx.headers.origin); 
    // http://localhost:9712/
    // ctx.set('Access-Control-Allow-Origin', 'http://localhost:9712');
    ctx.set('Access-Control-Allow-Headers', 'content-type');
    // 指定允許的跨域請求方法。可同時設定多個方法,多個方法用英文逗号(,)分隔。
    ctx.set('Access-Control-Allow-Methods', 'OPTIONS,GET,HEAD,PUT,POST,DELETE,PATCH')
    ctx.set('Access-Control-Allow-Credentials', true);
    // https://blog.csdn.net/qq_37301074/article/details/126037500
    // header("Set-Cookie:PHPSESSID=".session_id()."; HttpOnly;Secure;SameSite=None");
    // ctx.set("Set-Cookie","SameSite=None;Secure")
    // ctx.set(
    //     'Access-Control-Allow-Headers',
    //     'token,Content-Type,Content-Length, Authorization, Accept,X-Requested-With,domain,zdy' //當用戶端跨域并需要傳遞cookie時,需要設定Access-Control-Allow-Headers,并且值為不能為“*”,需要具體配置  代表允許上傳的請求頭字段
    // )

    await next();
});
           

設定session

/**
 * 配置 session
 * 官方: https://www.npmjs.com/package/koa-session
 * 教程: https://www.jianshu.com/p/86d43aca5cec
 */

const session_config = {
    /**  cookie的key。 (預設是 koa:sess) */
    key: 'msg',
    /**  session 過期時間,以毫秒ms為機關計算 。*/ // 1000ms = 1s
    maxAge: (1000 * 60) * 60 * 2,// 2 小時過期
    // maxAge: 1000 * 2,
    /** 自動送出到響應頭。(預設是 true) */
    autoCommit: true,
    /** 是否允許重寫 。(預設是 true) */
    overwrite: true,
    /** 是否設定HttpOnly,如果在Cookie中設定了"HttpOnly"屬性,那麼通過程式(JS腳本、Applet等)将無法讀取到Cookie資訊,這樣能有效的防止XSS攻擊。  (預設 true) */
    httpOnly: true,
    /** 是否簽名。(預設是 true) */
    signed: true,
    /** 是否每次響應時重新整理Session的有效期。(預設是 false) */
    rolling: true,
    /** 是否在Session快過期時重新整理Session的有效期。(預設是 false) */
    renew: false,
    
    // 測試
    // httpOnly: false,
};

const session = require('koa-session');
app.keys = ["12345"]	// session加密字段 // 這個是配合signed屬性的簽名key
app.use(session({...session_config}, app))
           

結果

添加一個計數器

// 一個簡單的計數器傳回,通路 http://localhost:3000 每次數字都會 +1
app.use(async (ctx, next) => {
    var session = ctx.session;
    session.count = session.count || 0;
    session.count++;
    ctx.body = ctx.session
    // ctx.body = ctx.session.counter;
})
           
徹底解決axios跨域,axios每次請求session都在不停變化的問題

很明顯計數不為1即為解決axios每次請求session都在不停變化,而web端口和伺服器端口不一緻,接口調用即為跨域成功.

啟發連結:

Vue通過axios跨域問題:Access to XMLHttpRequest at ‘http://127.0.0.1:8000/api/auction/‘ from origin …

繼續閱讀