nuxt配置代理 和 请求接口
一、安装
npm install @nuxtjs/axios @nuxtjs/proxy -S
// nuxt.config.js
{
...
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy'
],
axios: {
// 是否可以跨域
proxy: true,
// retry: { retries: 3 },
// baseUrl: process.env._ENV == 'production' ? 'xxx' : 'xxx'
},
proxy: {
'/api': {
target: 'http://localhost:4000',
pathRewrite: {
'^/api': ''
}
}
}
}
![]()
登录&获取个人信息
axiaos在项目中一定会进行二次封装的。封装的内容可能有所不同。
登录 我的 新闻
点击登录,它就跳转到登录页,那在登录页我就可以输入账号或者密码。当然,在正儿八经的项目里面,可能会有扫码登录或者验证码等等。所以我们先做个简易版的,先把逻辑走通先。就是用户名和密码登录。如果说它输入内容登录上了以后,就需要把token记录上。
存储之后,如果说他已经登录了,那点击到我的,它可以展示这个登录账号的一个头像或者昵称等等信息。如果说没有登录,点到我的,它会跳转到登录页,
当然新闻的话呢,是不需要登录的。就是登录没邓旒都可以进入到新闻页。
/pages/index.vue
<template>
<div>
<nuxt-link to="/login">登录</nuxt-link>
<nuxt-link to="/my">我的</nuxt-link>
<nuxt-link to="/news">新闻</nuxt-link>
</div>
</template>
<script>
export default {
name: 'IndexPage'
}
</script>
登录页
// login.vue
<template>
<div>
<h1>登录页</h1>
<input v-model="userName" />
<input v-model="userPwd" />
<button @click="login">登录</button>
</div>
</template>
<script>
export default {
return {
userName: '',
userPwd: ''
},
methods: {
login() {
}
}
}
</script>
然后安装包
cnpm install @nuxtjs/axios @nuxtjs/proxy -Ss
到config里面去配置:
// nuxt.config.js
{
...
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy'
],
axios: {
proxy: true
},
// 代理的地址
proxy: {
'/api': {
// 一般这里填域名
target: 'http://testapi.xxx.cn/'
}
}
}
然后就可以写接口了:
// login.vue
<template>
<div>
<h1>登录页</h1>
<input v-model="userName" />
<input v-model="userPwd" />
<button @click="login">登录</button>
</div>
</template>
<script>
export default {
return {
userName: '',
userPwd: ''
},
methods: {
login() {
this.$axios({
url: '/api/u/loginByJson',
method: 'post'
})
}
}
}
</script>
这里需要qs一下:
cnpm install qs -S
// login.vue
<template>
<div>
<h1>登录页</h1>
<input v-model="userName" />
<input v-model="userPwd" />
<button @click="login">登录</button>
</div>
</template>
<script>
export default {
return {
userName: '',
userPwd: ''
},
methods: {
login() {
let data = qs.stringify({
username: this.userName,
password: this.userPwd
})
this.$axios({
url: '/api/u/loginByJson',
method: 'post',
data
}).then(res => {
console.log(res)
})
}
}
}
</script>
qs用来处理url查询字符串的序列化和解析。
解析
将url查询字符串转为js对象:
import qs from 'qs';
const query = '?name=张三&age=21';
const result = qs.parse(query, { ignoreQueryPrefix: true });
// 结果:{ name: '张三', age: '21' }
序列化
将js对象转换为url查询字符串
const obj = {
name: '张三',
age: 21,
hobbies: ['1', '2']
}
const queryString = qs.stringify(obj);
// 结果 'name=张三&age=21$hobbies=1$hobbies=2'
// 嵌套对象
qs.stringify({ a: { b: { c: 'value' } } });
// 结果:'a[b][c]=value'
// 支持数组索引
qs.stringify({ a: [1, 2, 3] });
// 结果:'a[0]=1&a[1]=2&a[2]=3'
qs.stringify(obj, {
encode: true, // 是否编码(默认true)
arrayFormat: 'brackets', // 数组格式:indices/brackets/repeat
skipNulls: true, // 跳过null值
allowDots: true, // 使用点号表示嵌套:a.b.c=value
});
在请求中,为什么还要用一下qs.stringify()为了将对象正确地格式化为application/x-www-form-urlencoded格式。
解决axios默认行为问题。
axios默认情况下:
-
当data是对象时,会自动序列化为
application/json(json格式)。 -
有些后端接口要求
application/x-www-form-urlencoded格式。
qs.stringfy({
username: '张三',
password: '123'
})
// 结果 'username=%E5%BC%A0%E4%B8%89&password=123456'
请求头: Content-Type: application/x-www-form-urlencoded
![]()
登录成功后有一个token:
然后就需要把token给存储起来。下一步做的事就是如果我登录成功了,肯定要把token存进去,存到vuex里面,并且做到持久化存储。
点击我的,会显示个人信息在里边。获取个人信息。获取个人信息,需要把token携带过去。就有这样一个参数。这个时候就要针对axios进行二次封装了。
那么封装的内容就要在plugins里面。
// nuxt.config.ts
{
...
plugins: [
'~/plugins/axios'
],
...
}
plugins/axios.js
// axios.js
export default ({ $axios, store }) => {
// Request拦截器,设置token
$axios.onRequest((config) => {
})
$axios.onRequest((error) => {
})
$axios.onResponse((response) => {
return response.data;
})
}
二次封装封装的点特别多,比如说我们可以封装它的一个request拦截器去设置一个token。
![]()
在store下面设置vuex:
export const state = {
token: ''
}
// 因为要做服务端,服务端因为没有localstorage\cookie等,所以需要安装 cnpm install cookie-universal-nuxt -S
export const mutations = {
setToken(state, token) {
state.token = token
this.$cookies.set('token', token);
},
getToken(state) {
// 这里用中间件读取到token,然后在这个方法里面去设置token
state.token = this.$cookies.get('token');
}
}
并且要把cookie-universal-nuxt配置到modules里面:
// nuxt.config.js
{
...
modules: [
'cookie-universal-nuxt'
]
}
设置完成后,回到任何一个地方,它都有。然后我们需要认证守卫。
在这里我们需要把中间件创建一下,先在根目录创建middleware文件夹,然后在这下面创建一个auth.js文件,
在my页面做middleware:
// my.vue
<template>
<div>
<h1>我的</h1>
</div>
</template>
<script>
export default{
middleware: 'auth'
}
</scirpt>
middleware在my页面生效。这是我们读取出来的store。
// middleware/auth.js
export default ({ store }) => {
console.log(store.state);
}
然后获取token的值,我们已经持久化存到cookie了,可以commit去提交那个getToken。
// middleware/auth.js
export default ({ store }) => {
store.commit('getToken');
console.log(store.state);
}
然后就可以读取得到token了。
如果没有token的,就让他跳转到登录页:
// middleware/auth.js
export default ({ store, redirect }) => {
store.commit('getToken');
console.log(store.state);
if (!store.state.token) {
redirect('/login')
}
}
// login.vue
methods: {
...mapMutations(['setToken']),
login() {
let data = qs.stringify({
username: this.userName,
password: this.userPwd
});
this.$axios({
url: '/api/u/loginByJson',
method: 'post',
data
}).then(res => {
this.setToken(res.data.accessToken)
this.$router.push({
name: 'index'
})
})
}
}
如果没有登录,那么点击我的就会进入登录页,登录也填入账号和密码,点击登录,就会请求登录接口,然后获得token,token就会设置到cookie里面,再点击我的,就会可以查看自己的信息了,然后state.token会在中间件里又把本地cookie里面的token设置回去给它(完成持久性)。
做完之后,在我的页面,想要获得到个人信息,用户信息,所以在my.vue就可以做文章了:
// my.vue
<template>
<div>
<h1>我的</h1>
</div>
</template>
<script type="text/javascript">
export default {
middleware: 'auth',
async asyncData({ $axios }) {
let res = await $axios.get('/api/member/getInfo');
console.log(res);
}
}
</script>
请求的axios要全局封装,一定要带token:
// axios.js
export default ({ $axios }) => {
// Request拦截器,设置token
$axios.onRequest((config) => {
config.headers['Authorization'] = store.state.token;
})
// Error拦截器:出现错误的时候被调用
$axios.onRequest((error) => {
consolelog(222, error);
})
$axios.onResponse((response) => {
console.log(333, response)
return response.data
})
}