情景介紹:公司中有一個相似單點登陸的項目,主系統中有登陸後username和token,存放在瀏覽器的cookies中,如今改造的子系統須要拿到這兩個cookie值,再經過axios的設置header頭部信息去向後端請求數據,因爲使用了asyncData和nuxtServerInit方法,因此在服務端一開始就須要這兩個數據,可是又拿不到客戶端的cookie,查了不少資料vue
解決方案1 以下:這裏使用Nuxt插件的方法封裝Axiosnode
步驟一:在plugins目錄下新建axios-plugin.jsios
import axios from 'axios'
//開啓瀏覽器端cookie傳遞
axios.defaults.withCredentials=true
const EDU_SERVER_API='http://127.0.0.1/api/v2';
let options = {};
options.baseURL = EDU_SERVER_API
let ax = { options:options, get: (req,url) => { options.headers = { "Cookie": req.headers.cookie+";" }
url=options.baseURL+url;
return axios.get(url,options); }}
// 爲了在 asyncData 方法中使用
export default ({ app }, inject) => {
// Set the function directly on the context.app object
app.$global = {
ax:ax
}
};
複製代碼
步驟二 在Nuxt.config.js中新增pluginsvuex
plugins: [
'@/plugins/global',
{
src:'@/plugins/element-ui',
ssr: true,
},
'@/plugins/axios-plugin'
],
複製代碼
而後在AsyncData中使用express
export default {
async asyncData(params) {
return params.app.$global.ax.get(params.req, '/user/').then(res => {
return {user: res.data.user};
})
}
}
複製代碼
解決方案2element-ui
介紹:使用中間件axios
1. 經過 express 取得 cookies
在 server.js 上引入 cookies 解析中間件
constcookieParser =require('cookie-parser')
而且在路由前面 use
app.use(cookieParser())
2. 將 cookies 注入 render 的上下文中
app.get('*', (req, res) => {// 其餘代碼省略constcontext = {url: req.url,cookies: req.cookies }constrenderStream = renderer.renderToStream(context)// 其餘代碼省略})
3. 將 cookies 注入 vuex 的 store 中
在server-entry.js文件中, 將 cookies 注入到 store 中
exportdefaultcontext => {// 其餘代碼省略if(context.cookies) { store.state.cookies = context.cookies }// 其餘代碼省略}
這樣就能夠在組件中取到 cookies 了.
4. 封裝請求
這裏以 axios 爲例, 將 cookies 加載封裝函數的參數中:
注意: 這裏的封裝, 建議將瀏覽器用的和 node 用的分開
importaxiosfrom'axios'constparseCookie =cookies=>{letcookie =''Object.keys(cookies).forEach(item=>{ cookie+= item +'='+ cookies[item] +'; '})returncookie}exportdefault{ get(url, params, cookies = {}) {constcookie = parseCookie(cookies)returnaxios({method:'get', url, params,headers: {'X-Requested-With':'XMLHttpRequest', cookie } }) }}
5. 發起帶 cookies 參數的請求
在組件中 dispatch vuex 的 actions:
constfetchInitialData =async(store, config = {page:1}) => {awaitstore.dispatch('frontend/article/getList', config)}exportdefault{name:'frontend-index',prefetch: fetchInitialData,// 其餘代碼省略}
在 vuex 的 actions 中, 從 store 裏讀取 cookies, 做爲參數傳給請求接口的函數
async['getList']({commit,rootState: {cookies}}, config) {const{data: { data, code} } =awaitapi.get('/api/article/list', config, cookies)// 其餘代碼省略}
6. 幾個注意點
1, cookies的內容中不容許帶中文, 不知道從什麼版本開始, http-server 的 header 裏有中文就直接報錯
2,import store from '../store'這種方式下的 store 是不會帶 cookies 的
複製代碼
解決方案3(我使用的方案)後端
middleware下建立axiosMiddle.jsapi
import axios from 'axios'
import md5 from 'js-md5'
import cookies from 'js-cookie'
export default function({req,res}) {
if (req.headers !== undefined) {
let cookieArr = req.headers.cookie;
//獲取cookie而後拆成鍵值對
const getUserName = getCookie('name', cookieArr)
const getToken = getCookie('tiken', cookieArr)
//設置axios的全局變量.
axios.defaults.timeout = 60000 // 響應時間
// @requestParams
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
axios.defaults.headers.username = getUserName
axios.defaults.headers.token = getToken
axios.defaults.withCredentials = true
}
}
//解析瀏覽器中的cookies
function getCookie (name, strCookie) {
console.log('strCookie',strCookie)
var arrCookie = strCookie.split(';')
for (var i = 0; i < arrCookie.length; i++) {
var arr = arrCookie[i].split('=')
if (arr[0].trim() === name) {
return arr[1]
}
}
return {}
}
複製代碼
在nuxt.config,js中設置下使用中間件便可瀏覽器
router: {
middleware:'axiosMiddle'
},
複製代碼
至此,結束