跨域
问题说明:当下最流行的就是前后端分离开发,前端项目和后端接口并不在同一个域名下,那么必然会出现跨域问题,这种跨域问题是出现在开发的过程中的,而部署上线出现的跨域问题是生产环境中的,与前端开发无关系,由运维人员负责,可以使用Nginx反向代理,在此不做介绍。
关于开发环境中的跨域问题的几种解决方式如下:
- jsonp(原理是动态添加一个script标签,src属性没有跨域限制,存在安全隐患,只支持get请求)
- vue-cli代理(webpack反向代理配置devserver配置代理地址)
- cors(后端小伙伴做跨域资源共享配置,前端设置允许携带cookie值
axios.defaults.withCredentials=true)
为什么会有跨域的错误
你项目中请求的接口地址与你本地的服务器不同源。
- 协议,域名,端口 有一个不相同(不同源)
就会出现跨域请求,如果此时你的后端接口是允许跨域的,则浏览器也不会报错,所以需要解决跨域错误的情况要满足如下三个条件:
你的浏览器不给力(同源策略)。
可以安装这个chrome插件,来绕过浏览器的限制。

你的请求真是跨域了。

后端请求不允许跨域请求。
所以,出现跨域的请求,如果后端接口服务器已经处理了,则可以正常访问;而如果后端没有处理,则会报错,此时,就需要我们前端来介入了。

vue项目中跨域如何解决
先验知识:
如果是两台服务器之间相互请求接口,则不会出现跨域请求错误(跨域请求错误是浏览器报的)
思路:
通过本地服务器来代理请求

准备工作
安装axios,express这两个包。
# 用来发ajax请求
npm i axios
# 用来快速创建接口服务器,模拟后端
npm i express -D
准备服务器
在src/server下创建文件express_server.js内容如下:
const express = require('express')
const url = require('url')
const app = express()
function fullUrl (req) {
console.dir(req.headers.host)
return url.format({
protocol: req.protocol,
host: req.get('host'),
pathname: req.originalUrl
})
}
app.use((req, res, next) => {
// console.dir(req)
console.log(Date.now(), fullUrl(req))
// 打开下面四句代码用来处理跨域请求,如果开启,则不会出现跨域错误
// res.header('Access-Control-Allow-Origin', '*')
// res.header('Access-Control-Allow-Headers', 'Content-Type')
// res.header('Access-Control-Allow-Methods', '*')
// res.header('Content-Type', 'application/json;charset=utf-8')
next()
})
app.get('/api/v1_0/user', (req, res) => {
res.json({
a: 1, b: 2
})
})
app.get('/api/v1_0/channels', (req, res) => {
res.json({
a: 11, b: 2
})
})
app.listen('5000', () => {
console.log(5000)
})
启动服务器
node express_server.js
测试
http://localhost:5000/api/v1_0/user
准备客户端
对axios进行二次封装
在src/util/request.js
import axios from 'axios'
const instance1 = axios.create({
// baseURL: 'http://ttapi.research.itcast.cn'
baseURL: 'http://localhost:5000'
// baseURL: '/api'
})
const instance2 = axios.create({
baseURL: 'http://www.com2.com'
})
export { instance1, instance2 }
export default instance1
在login.vue中发起请求
import ajax from '@/utils/request.js'
async login () {
await ajax({
methods: 'get',
url: '/api/v1_0/channels'
// url: 'api/user'
})
}
观察结果
跨域错误
解决跨域
后端支持跨域
把express写的接口服务器中的跨域处理打开:
app.use((req, res, next) => {
// console.dir(req)
console.log(Date.now(), fullUrl(req))
// 打开下面四句代码用来处理跨域请求,如果开启,则不会出现跨域错误
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Content-Type')
res.header('Access-Control-Allow-Methods', '*')
res.header('Content-Type', 'application/json;charset=utf-8')
next()
})
重启服务器,再发请求。
vue配置 vue-cli代理服务
通过在vue.config.js中补充devServer项的配置。
具体步骤:
更改request.js中的baseUrl的设置
去掉baseUrl即可。此时,没有配置基地址,它会自动补全http://localhost:8080

补充vueconfig.js中的配置
vue.config.js
module.exports = {
publicPath: './'
devServer: {
// 代理把/api的请求转到target里面
proxy: {
'/api': {
target: 'http://localhost:5000',
// // changeOrigin: false, // 请求头是 本地服务器 localhost:8080
changeOrigin: true, // 请求头是 target
pathRewrite: {
// // '^/api': '/api/haha'
// // 把路径中的/api改成/api/haha
// // 示例:http://localhost:8080/api/v1_0/user ----> http://localhost:5000/api/haha/v1_0/user
'^/api': '' // 路径重写
// 把路径中的/api改成空格,相当于去掉/api
// 示例:http://localhost:8080/api/v1_0/user ----> http://localhost:5000/v1_0/user
// '^/api': '/api11'
// // 把路径中的/api 改成/api11
// // 示例:http://localhost:8080/api/v1_0/user ----> http://localhost:5000/api11/v1_0/user
}
// }
// }
// }
}
注意:
- 修改了配置文件要重启服务
- 时时观察后端服务器的输出效果
小结
跨域不是vue的问题;
原因:
- 浏览器的同源策略
- 后端接口没有对请求进行跨域处理
在vue在开发阶段,它会起一个服务器,(localhost:8080) ,我们可以通过vue.config.js中设置代理,通过服务器来去向接口发请求。
如果打包上线(dist目录),则devServer.proxy就无法用了。