Axios异步请求跨域解决方案
场景
后端 127.0.0.1(默认 80);前端 127.0.0.1:8081
在 vue 开发过程中使用 axios 发起 POST 请求:
1 | axios({ |
会报跨域错误:
原因是浏览器同源策略,只有 同协议、同域名、同端口 三同的地址才能互相通过 AJAX 的方式请求。而上面情形虽然协议(http)和域名(127.0.0.1)都相同,但端口不同(80 和 8081),所以无法正常请求。
解决方案
方案一
服务端添加响应头,以 Koa 为例,在 app.js
中添加响应头:
1 | app.use(async (ctx, next) => { |
这样设置会允许任何来源(*)的跨域。
但往往后端的某些接口是需要身份验证的,比如用户对文章、商品之类的进行评论或点赞,就需要用户登录才能操作。这种情况下就需要使用到 cookie 或者 session ,所以还得设置 Access-Control-Allow-Credentials
为 true ,表示在 CORS 请求中允许客户端发送 cookie 。然而一旦这样设置,Access-Control-Allow-Origin
就不能再是通配符 *
,必须指定具体的域,所以服务端最终的 header 设置为:
1 | app.use(async (ctx, next) => { |
后端这样设置后,前端就能够实现跨域请求了。
方案二
如果服务端不加 ctx.set("Access-Control-Allow-Origin", "*");
这一段。可以在 @vue-cli
中 配置代理 。也就是 前端设置代理 的解决方案。
原理
利用后端不存在跨域问题,而让 vue 服务器代为获取数据。因为启动 vue 项目本质上也是用 node 启了个服务器(127.0.0.1:8080),配置了代理后,就不再是浏览器直接请求我们在 axios 中配置的 http://127.0.0.1/(默认80端口) ,而是用 vue 启动的这个服务器去请求 http://127.0.0.1/ 这个接口,由于后端相互之前请求不存在跨域问题,所以能获取数据,获取后给到前端。
在前端项目根目录下新建 vue.config.js
文件:
1 | module.exports = { |
前端发送 POST 跨域请求
上面也提到了,前端有时候往往不止需要发送 GET 请求,POST 请求也是常有的事儿。所以还需要对 Axios 进行如下配置:
vue 项目下的 main.js 中全局配置 axios
1 | import axios from 'axios'; |
由于需要把请求时的数据序列化为 url 的形式,所以要下载 qs 包
1 | npm i qs |
在具体页面中发送 POST 请求
1 | import qs from 'qs' |