方案1:webpack
其他网址
VUE axios 跨域问题 No 'Access-Control-Allow-Origin' header is present on the requested resource._王小二的博客-CSDN博客
json - Vue Axios CORS policy: No 'Access-Control-Allow-Origin' - Stack Overflow
基础
其他网址
GitHub - chimurai/http-proxy-middleware
vue-cli proxyTable中跨域中pathRewrite 怎么用 - SegmentFault 思否
devServer
devServer:开发服务器代理。
proxyTable的pathRewrite
pathRewrite使用正则表达式
示例:
'proxyFor/abc':{ // 要代理的接口名 target:'http://siwei.me', // 要代理的根地址 changeOrigin:true, // 允许跨域 pathRewrite:{'^/abc':''} // 接口名重写 }
含义:^/abc应该拆分为“^”和“/abc”,“^”匹配字符串最开始的位置。
比如:/abc/def/gh;经过 http-proxy-middleware 的代理服务器时,会变成"/def/gh",与“target”拼接,组成:"http://siwei.me/def/gh"
使用代理之前
router/index.js
import Vue from 'vue' import Router from 'vue-router' import Axios from 'axios'; import VueAxios from 'vue-axios'; import FormSubmit from "@/components/FormSubmit"; Vue.use(Router) Vue.use(VueAxios, Axios); export default new Router({ routes: [ { path: '/form_submit', name: 'formSubmit', component: FormSubmit } ] })
components/FormSubmit.vue
<template> <div> <textarea v-model='content'> </textarea> <br/> <input type='button' @click='submit' value='留言'/> </div> </template> <script> export default { data() { return { content: '' } }, methods: { submit: function () { this.axios.post('http://siwei.me/interface/blogs/add_comment', { content: this.content } ) .then((response) => { alert("提交成功!, 刚才提交的内容是:" + JSON.stringify(response)); }, (response) => { alert("出错了") } ) } } } </script>
config/index.js
采用默认配置。
... module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: {}, ... }
结果
使用代理之后
config/index.js
修改proxyTable
... module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { '/abc':{ // 要代理的接口名 target:'http://siwei.me', // 要代理的接口地址 changeOrigin:true, // 允许跨域 pathRewrite:{'^/abc':''} // 接口名重写 } }, ... }
可以代理所有 //下边这样配置时,接口是啥就写啥。对本处来说:this.axios.post('/interface/blogs/add_comment',
... module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { '/':{ // 要代理的接口名。本处也可以用'**' target:'http://siwei.me', // 要代理的接口地址 changeOrigin:true, // 允许跨域 } }, ... }
可以配置多个代理接口的,就是普通的json格式。例如:
... module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { '/abc':{ // 要代理的接口名 target:'http://siwei.me', // 要代理的接口地址 changeOrigin:true, // 允许跨域 pathRewrite:{'^/abc':''} // 接口名重写 }, '/def':{ // 要代理的接口名 target:'http://siwei.me', // 要代理的接口地址 changeOrigin:true, // 允许跨域 pathRewrite:{'^/def':''} // 接口名重写 } }, ... }
router/index.js(跟上边一样)
import Vue from 'vue' import Router from 'vue-router' import Axios from 'axios'; import VueAxios from 'vue-axios'; import FormSubmit from "@/components/FormSubmit"; Vue.use(Router) Vue.use(VueAxios, Axios); export default new Router({ routes: [ { path: '/form_submit', name: 'formSubmit', component: FormSubmit } ] })
components/FormSubmit.vue
<template> <div> <textarea v-model='content'> </textarea> <br/> <input type='button' @click='submit' value='留言'/> </div> </template> <script> export default { data() { return { content: '' } }, methods: { submit: function () { this.axios.post('/abc/interface/blogs/add_comment', { content: this.content } ) .then((response) => { alert("提交成功!, 刚才提交的内容是:" + JSON.stringify(response.data)); }, (response) => { alert("出错了") } ) } } } </script>
结果
方案2:@vue/cli 3
其他网址
简介
跟webpack-dev-server一样用(除了配置位置不一样以外)。
注意事项
配置http格式
其他网址
使用Vue的axios vue-resource跨域不成功 但原生xhr就可以 - SegmentFault 思否
vue中使用axios的多种方式 - 简书axios官网:https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format
简介
axios 发送请求时的数据默认是 JSON 格式的。这是导致用 axios POST 跨域出错的主要原因。
根据 CORS 的标准,当浏览器发送跨域请求时,如果请求不是GET或者特定POST(Content-Type只能是 application/x-www-form-urlencoded, multipart/form-data 或 text/plain的一种)时,强烈要求浏览器必须先以 OPTIONS 请求方式发送一个预请求(preflight request),从而获知服务器端对跨源请求所支持 HTTP 方法。使用 axios 直接发送 POST 的跨域请求,如果web后端对 OPTIONS 的响应有问题,就会报错。
用 axios 解决跨域的方案和你类似,不过是先把 params 转换为字符串格式了,见上边的官方用x-www-form-urlencoded格式的说明。
实例: post方法使用application/x-www-form-urlencoded格式
1.设置 headers:{ 'Content-type': 'application/x-www-form-urlencoded'}
axios.post('url',data,{headers:{ 'Content-type': 'application/x-www-form-urlencoded'}}) // 不想在每次请求都设置的话,可以集中设置下 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
2.使用qs
仅仅第一步并没有达到想要的效果,post的body主体中还是{"age":10}这样的格式,并不是我们想要的query参数。引入Qs,这个库是axios里面包含的,不需要再下载了
import qs from 'qs'; import axios from 'axios'; let reqUrl = 'http://xxx.com'; let reqParams = { name: 'aaa' }; axios.post(url, qs.stringify({ params: reqParams })).then(response => { console.log(response); })
其他
跨域的cookie丢失
axios默认是不让ajax请求头部携带cookie的,设置 axios.defaults.withCredentials = true 即可