後端折騰完了,折騰前端
之前為了圖省事,我們選擇了Apollo Boost...出來混終究是要還的,為了配置攔截器,還得用Apollo Client.當然,也許是我不知道怎麼配置Apollo Boost,如果有誰知道告訴我一聲.
首先安裝必要的包:
npm install -S apollo-cache-inmemory apollo-client apollo-link apollo-link-context apollo-link-http graphql-tag apollo-link-error
首先修改utils/apollo.js,每一段的用處,有注釋,就不一一說了. token我這裡直接寫死了 :
import {ApolloClient} from 'apollo-client'
import {HttpLink} from 'apollo-link-http'
import {InMemoryCache, IntrospectionFragmentMatcher} from 'apollo-cache-inmemory'
import {ApolloLink} from 'apollo-link'
import {onError} from 'apollo-link-error'
const httpLink = new HttpLink({
uri: 'http://127.0.0.1:9090/graphql', //請求路徑
credentials: 'include' // 請求需要帶入cookie則配置
})
const middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: {
'token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0IiwiZXhwIjoxNTgzNDk5OTE1LCJpc3MiOiJkZW1vIn0.5tXTOiLHTlRM1Uf7WHpTNyA1BaClaDz3QnfYJsHauF8',
// 'token': sessionStorage.getItem('token') || ${token} || null
}
}) //request攔截器
return forward(operation).map(response => {
return response
}) //response攔截器
})
// 錯誤響應攔截器
const errorLink = onError(({networkError, response}) => {
let errorMsg = ''
if (!!response && response.errors !== undefined && response.errors.length) {
errorMsg = !response.errors[0].message ? '伺服器錯誤' : response.errors[0].message
}
if (networkError) {
errorMsg = networkError.message
if (networkError.result !== undefined) {
errorMsg = networkError.result.success === false ? networkError.result.message : networkError.result.error
}
}
if (errorMsg) {
console.log('apollo client error: ' + errorMsg)
}
})
const authLink = middlewareLink.concat(httpLink)
const defaultOptions = {
watchQuery: {
fetchPolicy: 'network-only',
errorPolicy: 'ignore'
},
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all'
}
}
// 支援聯合查詢
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData: {
__schema: {
types: [
{
kind: 'INTERFACE',
name: 'Document',
possibleTypes: [
{name: 'MyInterface1'},
{name: 'SomeInterface2'}
]
}
]
}
}
})
// 需要添加請求頭
export const apolloClient = new ApolloClient({
link: errorLink.concat(authLink),
cache: new InMemoryCache({fragmentMatcher}),
connectToDevTools: true,
defaultOptions: defaultOptions
})
// 不需要添加請求頭
export const baseClient = new ApolloClient({
link: httpLink,
cache: new InMemoryCache({fragmentMatcher}),
connectToDevTools: true,
defaultOptions: defaultOptions
})
main.js也要修改一下:
import Vue from 'vue'
import VueApollo from 'vue-apollo'
import {apolloClient,baseClient} from './utils/apollo'
import App from './App.vue'
Vue.config.productionTip = false
const apolloProvider = new VueApollo({
clients: {
api: apolloClient, //需要添加請求頭
base: baseClient
},
defaultClient: baseClient //預設請求路徑,如果隻有一個請求就使用這個就行
})
// Vue.use(VueApollo)
new Vue({
apolloProvider,
render: h => h(App),
}).$mount('#app')
graphql/article.js做一個小修改:
import gql from 'graphql-tag'
import {apolloClient,baseClient} from '../utils/apollo'
// 文章清單
export function getArticles(params) {
return baseClient.query({ //不需要帶上token
query: gql `{
articles{
id
title
content
}
}`,
variables: params
})
}
// 單篇文章詳情
export function getArticle(params) {
return apolloClient.query({ //需要帶上token
query: gql `query ($id : Int) {
article(id: $id) {
id
title
content
}
}`,
variables: params
})
}
其它都不用改
npm run serve
如果檢視文章詳情,沒有帶上正确的token,浏覽器console可以看到"apollo client error: signature is invalid"