我在開發過程中遇到這兩個問題,找了很多貼子但是都沒解決我的問題.
一個偶然,讓我走出困境,
問題
- axios跨域請求
- axios每次請求session都在不停變化
解決辦法
- axios使用代理服務解決跨域
- axios+vue請求時攜帶cookie,來解決axios每次請求session都不停變化
axios跨域
封裝axios為http.js,将http.js在main.js
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;
})
很明顯計數不為1即為解決axios每次請求session都在不停變化,而web端口和伺服器端口不一緻,接口調用即為跨域成功.
啟發連結:
Vue通過axios跨域問題:Access to XMLHttpRequest at ‘http://127.0.0.1:8000/api/auction/‘ from origin …