最近在自己写前后端分离的项目,前台用 vue ,后台用 PHP 框架写接口(PhalApi),然后在 vue 中用 axios 调用 PHP 的接口,遇到了跨域请求的问题,在网上了找了各种解决方法,结果就是没解决了,最后还是自己捣鼓出来了,主要是因为我在修改 vue 项目中的 config/index.js 文件中这个配置时就是不好使,所以才不得已用的别的方法。


vue index.js 配置.png

你如果查询 axios 跨域的话应该也是这个方法,具体我就不解释了,然后我不管怎么设置,这个配置就是不好使,真的是把你气死,没办法,幸亏我是自己开发前后台,所以我还有第二种解决方法,就是从后台下手,我用的是

Phal 框架,然后我就用设置请求头的方式解决了这个问题

在项目的主入口文件中加入以下这行代码;

/public/index.php
// 设置允许 http://172.24.42.65:8000 这个地址跨域请求
header('Access-Control-Allow-Origin:http://172.24.42.63:8080');

因为我是在本地开发,一开始我设置的是

header('Access-Control-Allow-Origin:http://localhost:8080');

但是这个函数好像不会解析 localhost 所以我就替换成了 IP 地址,然后 vue 端的配置文件中,我也把服务器的默认打开端口从 localhost 改成了 172.24.42.63

/config/index.js

vue 服务器端口设置.png

这个时候我在执行 axios 请求就不会有跨域的问题了,开心的一批。

然后上面这种做法只能解决 axios 发送普通的 get 请求时遇到的问题,如果我们要发送 post 请求,这时还是不可以的,你会发现你会遇到下面这个提示


axios 跨域问题.png

Failed to load http://localhost:8888/?s=User.saveAddress: Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response

这里我们有两种解决方法,分别是前端和后端

先说前端:

我们在发送 axios 请求的时候,需要设置一下我们的请求头,也就是下面这个东东

axios({
headers: {
'Content-Type':'application/x-www-form-urlencoded'
}
});

成功解决


跨域成功.png

再说后端:

后端的话你就需要在 Phal 框架入口的地方再设置一下这个东东

/public/index.php
header('Access-Control-Allow-Headers:content-type');

成功解决


跨域成功.png

你以为这就万事大吉了,NO,NO,NO,那说明少年你还是太天真,让你感受一下啥叫不认真学习的后果,接下来你又会遇到这个问题


axios post 发送请求.png

纳尼,我辛辛苦苦的弄了半天,你告诉我参数没有接收到??????

然后本猿就开始了各种捣鼓,百度,最终发现是自己 axios 传输参数的时候有问题, 一开始我是这个传输 post 参数的

axios({
url: '/s=User.saveAddress',
method: 'post',
data: {
user_id: 1,
username: 'haha'
},
headers: {
'Content-Type':'application/x-www-form-urlencoded'
}
})
.then(response=>{
console.log(response.data)
})

乍一看仿佛并没有什么问题,本猿还去查看了以下别人的代码,感觉和我都差不多,然后,它就是死活都传不过去,我的天,此时此刻仿佛有无数的 ret:400 在我眼前围绕,真是无比酸爽。

最终我看翻看某位大神的博客里发现了一些不同,这都是自己以前留下的帐,之前没好好学,现在就找上门来了,

这里我们因为用的是 application/x-www-form-urlencoded 这种编码,也就是说我们只需要在前台把数据处理好

就行了,不需要后台再去处理了,让我们把刚才的代码改造一下

const qs = require('qs');
const data = {
"User_id" : 1,
"Phone" : addressInfo.phone,
"Address" : addressInfo.address,
"Username" : addressInfo.username
}
axios({
url:'/?s=User.saveAddress',
method: 'post',
data: qs.stringify(data),
headers:{
'Content-Type':'application/x-www-form-urlencoded'
}
})
.then(response=>{
console.log(response.data);
})

这里我们引入了 qs 这个模块,然后用它的功能 qs.stringify(data) 然后再传输数据,这样后台就能解析我们传的值了,问题完美解决,累死了。