VUE跨域问题
解决Vue跨域问题
跨域
1、当前网页URl与请求的URL地址不同域名。
2、当前网页URl与请求的URL相同域名,不同端口。
3、当前网页URl与请求的URL不同协议。
即域名、端口和协议必须一样,不然就属于跨域请求。
比如我现在在WebStrom运行vue项目,默认分配的端口号是8080,也就是我当前的项目打开的网页域名和端口号是
http://localhost:8080/
此时我想请求本地的apche服务器的后端文件,例如:
http://localhost/php/insert.jsp
默认端口为80,所以该url没有显示端口号
如何解决
原理
每次发送axios请求时,由于设置了axios.defaults.baseURL = ‘api’;所以自动会在请求的url前加上’ api/ ‘,然后vue.cofig.js中的代理检测到url中包含’ api/ ‘,就会将’ api/ '以及之前的部分替换为"tartget"属性的值,从而实现请求url的转换,让目的服务器“误以为”是自己服务器下程序发送的请求。就达到了跨域的目的。
我们也可以通过跨域来实现本地服务器上的网页请求其他网站的数据,但是现在很多网站已经对跨域请求做了限制,所以不一定都能成功。
vue脚手架4版本以下
打开config/index.js文件,dev中添加
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api' :{
//目标服务器的域名
target: 'http://localhost:7013',
// 在本地会创建一个虚拟服务端,然后发送请求数据,并同时接收返回的数据,实现代理服务器与目标服务器的数据交换
changeOrigin: true,//允许跨域
pathRewrite: {
// 替换target中的请求地址,当你请求目标服务器http://localhost:3000这个地址的时候,直接写成/api即可
'^/api': ''
},
}
},
创建axios模块,src中创建axios
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5p8L12Qe-1682471955939)(C:/Users/不败/AppData/Roaming/Typora/typora-user-images/image-20230423091027705.png)]
/*
ajax请求函数模块 ajax.js
返回值: promise对象(异步返回的数据是: response.data)
*/
import axios from 'axios'
export default function ajax (url, data = {}, type = 'GET') {
return new Promise(function (resolve, reject) {
// 执行异步ajax请求
let promise
if (type === 'GET') {
// 准备url query参数数据
let dataStr = '' // 数据拼接字符串
Object.keys(data).forEach(key => {
dataStr += key + '=' + data[key] + '&'
})
if (dataStr !== '') {
dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'))
url = url + '?' + dataStr
}
// 发送get请求
promise = axios.get(url)
} else {
// 发送post请求
promise = axios.post(url, data)
}
promise.then(function (response) {
// 成功了调用resolve()
resolve(response.data)
}).catch(function (error) {
//失败了调用reject()
reject(error)
})
})
}
axios通用模api.js
/*
包含n个接口请求函数的模块 api.js
函数的返回值: promise对象
*/
import ajax from './ajax'
const BASE_URL = '/api'
// 1.在proxy中设置要访问的地址,并重写/api为空的字符串,因为我们真正请求的地址是没有带/api,这个重写很重要!!!
// 2.在创建axios实例的时候将baseURL设置为/api ,这时候我们的跨域就已经完成了。
// 3. 假如请求的真正地址为:http://localhost:7013/login_pwd,但我们在浏览器上会看到是这样的 :http://localhost:7013/api/login_pwd ,多了个/api,但并不影响我们请求数据
export const reqPwdLogin = ({username, password}) =>
ajax(BASE_URL + '/loginpwd', {username, password}, 'POST')
export const textapi = ({i5, name}) =>
ajax(BASE_URL + '/textapi', {i5, name}, 'POST')
index.js添加axios通用模板
proxyTable: {
'/api' :{
//目标服务器的域名
target: 'http://localhost:7013',
// 在本地会创建一个虚拟服务端,然后发送请求数据,并同时接收返回的数据,实现代理服务器与目标服务器的数据交换
changeOrigin: true,//允许跨域
pathRewrite: {
// 替换target中的请求地址,当你请求目标服务器http://localhost:3000这个地址的时候,直接写成/api即可
'^/api': ''
},
}
},
vue脚手架4以上
vue脚手架4以上无config文件夹解决方法
vue-cli3以后配置文件被隐藏了,这里需要在项目根目录下(与src文件夹同级)创建vue.config.js文件来修改默认的配置:
vue.config.js加入以下代码
devServer: {
proxy: {
//名字可以自定义,这里我用的是api
'/api': {
target: 'http://localhost:7013',//设置你调用的接口域名和端口号
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
main.js中添加
Vue.prototype.HOST = '/api' // 封装跨域接口
目的是让每次axios发起请求时,请求的url都会加上’api/’
最后创建axios模块,和通用模板,如上:
vue无router文件夹解决方法
首先,查看package.json中有没有router的依赖,如果没有的话执行下面图片中的语句。
cnpm install vue-router --save
新建一个router文件夹,在文件夹下新建一个index.js文件
import Vue from 'vue'
import Router from 'vue-router'
//对应你要跳转的组件
import Home from '../views/Home'
import About from '../views/About'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/Home',
name: 'Home',
component: Home
},
{
path: '/About',
name: 'About',
component: About
}
]
})
在main.js中引入