[TOC]
>[success] # 解决跨域问题
在下面表格中列出了 **跨域** 的案例:
| URL | 说明 | 是否允许通信 |
| --- | --- | --- |
| http://www.d.com/d.js <br/>http://www.d.com/w.js | 同一域名下 | 允许 |
| http://www.d.com/lab/a.js <br/>http://www.d.com/src/b.js | 同一域名下不同文件夹 | 允许 |
| http://www.d.com:3333/a.js <br/>http://www.d.com:4444/b.js | 同一域名不同端口 | 不允许 |
| http://www.d.com/a.js <br/>http://46.33.22.44/b.js | 域名和域名对应 IP | 不允许 |
| http://www.d.com/a.js <br/>http://scipt.d.com/b.js | 主域相同,子域不同 | 不允许 |
| http://www.d.com/a.js <br/>http://d.com/b.js | 同一域名,不同二级域名(同上) | 不允许(cookie 这种情况下也不允许访问) |
| http://www.d.com/a.js <br/>http://www.v.com/b.js | 不同域名 | 不允许 |
**跨域** 是受到 **浏览器** 的 **同源策略** 的影响,在一些情况下是 **不允许通信的** 。
>[success] ## 前端解决跨域
**前端** 需要在 **vue.config.js** 文件中通过 **devServer** 中的 **proxy** 来 **配置代理** 。
**原理** :我们在 **本地开发** 的时候,通过 **vueServe** 起一个 **本地的开发服务** ,这个 **服务的地址** 一般是 **localhost** , **端口** 一般是 **8080** ,如果我们在 **本地起一个 node 服务** ,那么它的 **端口** 肯定是跟我们的 **前端服务的端口** 是不一样的,刚才在 上面表格中讲过 **同一域名不同端口** 也是 **存在跨域问题** ,是 **不在同一个域下** ,这个时候 **调用接口** 的话,受到 **同源策略** 影响,是 **无法调取成功** 的,我们可以用 **proxy** 来 **设置代理** , **它会把我们所有的接口,代理到目标URL下** ,比如接口是 **/api/getUserInfo** ,我们 **设置代理** 是 **http://localhost:4000** ,这样的话请求的接口就会被代理到 **http://localhost:4000** 下,代理后请求接口时的**URL** : **http://localhost:4000/#/api/getUserInfo** , 例子如下:
**vue.config.js**
~~~
const path = require('path') // 引入nodejs的path模块
const resolve = dir => path.join(__dirname, dir) // resolve方法用来加载路径
const BASE_URL = process.env.NODE_ENV === 'production' ? '/iview-admin/' : '/' // 判断当前为开发环境还是打包环境, '/'意思是代表指定在域名的根目录下,如果要指定到iview-admin下就这样写'/iview-admin/', production为生产坏境,development为开发环境
module.exports = {
lintOnSave: false, // 取消每次保存时都进行一次' ESLint '检测
publicPath: BASE_URL, // 项目的基本路径,vuecli2.0时打包经常静态文件找不到,就是需要配置这个属性为'./'
chainWebpack: config => { // 配置Webpack
config.resolve.alias
.set('@', resolve('src')) // 引入文件时候“ @ ”符号就代表src
.set('_c', resolve('src/components')) // 引入组件文件夹中的文件就可以用“ _c ”代替src/components
},
productionSourceMap: false, // 打包时不生成.map文件,会减少打包体积,同时加快打包速度
devServer: { // 跨域有2种解决方案: 1. 在后端的header中配置, 2. 使用devServer来配置代理解决跨域
proxy: 'http://localhost:4000' // 这里写需要代理的URL,这里会告诉开发服务器,将任何未知请求匹配不到静态文件的请求,都代理到这个URL来满足跨域
}
}
~~~
这里的代理的 **URL地址** 以及 **端口号** 一定要与服务端 **一致** 。
>[warning] ### 注意
1. **前端配置代理** 只是在 **开发环境(develop)** 好用,便于开发,在 **生产环境(prod)** 还是 **需要由服务端解决跨域** 。
2. 这里需要注意,如果在 **前端配置代理** ,需要在 **src/config/index.js(接下来的axios封装中用到了这个文件)** 中添加一个 **逻辑判断** 如下:
**src/config/index.js**
~~~
// 如果当前是生产环境用生产环境地址,如果是开发环境并且在vue.config.js中配置了代理,就用空字符串【''】,如果未配置代理就用开发环境地址
export const baseURL= process.env.NODE_ENV === 'production' ? 'http://production.com' : 'http://develop.com'
// 配置了代理的情况下这样写
export const baseURL= process.env.NODE_ENV === 'production' ? 'http://production.com' : ''
~~~
>[success] ## 后端解决跨域
如果不在 **设置代理** ,可以在 **后端设置header** 来 **解决跨域问题** ,这里 **后端** 用的是 **nodejs** ,在**express(nodejs的框架)** 里使用 **app.all** 为 **所有请求** 都添加这 **3 个 header** 即可。
**app.js**
~~~
var createError = require('http-errors')
var express = require('express')
require('colors')
var path = require('path')
var cookieParser = require('cookie-parser')
var logger = require('morgan')
var indexRouter = require('./routes/index')
var usersRouter = require('./routes/users')
var app = express()
// view engine setup
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'jade')
app.use(logger('dev'))
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, 'public')))
app.all('*', function(req, res, next) { // 设置header
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type')
res.header('Access-Control-Allow-Methods','PUT,POST,GET,DELETE,OPTIONS')
next()
})
app.use('/', indexRouter)
app.use('/users', usersRouter)
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404))
})
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message
res.locals.error = req.app.get('env') === 'development' ? err : {}
// render the error page
res.status(err.status || 500)
res.render('error')
})
module.exports = app
~~~
- vue 26课
- Vue-cli3.0项目搭建
- Vue-ui 创建cli3.0项目
- Vue-ui 界面详解
- 项目目录详解
- public文件夹
- favicon.ico
- index.html
- src文件夹
- api文件夹
- assets文件夹
- components文件夹
- config文件夹
- directive文件夹
- lib文件夹
- mock文件夹
- mock简明文档
- router文件夹
- store文件夹
- views文件夹
- App.vue
- main.js
- .browserslistrc
- .editorconfig
- .eslintrc.js
- .gitignore
- babel.config.js
- package-lock.json
- package.json
- postcss.config.js
- README.en.md
- README.md
- vue.config.js
- Vue Router
- 路由详解(一)----基础篇
- 路由详解(二)----进阶篇
- Vuex
- Bus
- Vuex-基础-state&getter
- Vuex-基础-mutation&action/module
- Vuex-进阶
- Ajax请求
- 解决跨域问题
- 封装axios
- Mock.js模拟Ajax响应
- 组件封装
- 从数字渐变组件谈第三方JS库使用
- 从SplitPane组件谈Vue中如何【操作】DOM
- 渲染函数和JSX快速掌握
- 递归组件的使用
- 登陆/登出以及JWT认证
- 响应式布局
- 可收缩多级菜单的实现
- vue杂项
- vue递归组件
- vue-cli3.0多环境打包配置
- Vue+Canvas实现图片剪切
- vue3系统入门与项目实战
- Vue语法初探
- 初学编写 HelloWorld 和 Counter
- 编写字符串反转和内容隐藏功能
- 编写TodoList功能了解循环与双向绑定
- 组件概念初探,对 TodoList 进行组件代码拆分
- Vue基础语法
- Vue 中应用和组件的基础概念
- 理解 Vue 中的生命周期函数
- 常用模版语法讲解
- 数据,方法,计算属性和侦听器
- 样式绑定语法
- 条件渲染
- 列表循环渲染
- 事件绑定
- 表单中双向绑定指令的使用
- 探索组件的理念
- 组件的定义及复用性,局部组件和全局组件
- 组件间传值及传值校验
- 单向数据流的理解
- Non-Props 属性是什么
- 父子组件间如何通过事件进行通信
- 组件间双向绑定高级内容
- 使用匿名插槽和具名插槽解决组件内容传递问题
- 作用域插槽
- 动态组件和异步组件
- 基础语法知识点查缺补漏
- Vue 中的动画
- 使用 Vue 实现基础的 CSS 过渡与动画效果
- 使用 transition 标签实现单元素组件的过渡和动画效果
- 组件和元素切换动画的实现
- 列表动画
- 状态动画
- Vue 中的高级语法
- Mixin 混入的基础语法
- 开发实现 Vue 中的自定义指令
- Teleport 传送门功能
- 更加底层的 render 函数
- 插件的定义和使用
- 数据校验插件开发实例
- Composition API
- Setup 函数的使用
- ref,reactive 响应式引用的用法和原理
- toRef 以及 context 参数
- 使用 Composition API 开发TodoList
- computed方法生成计算属性
- watch 和 watchEffect 的使用和差异性
- 生命周期函数的新写法
- Provide,Inject,模版 Ref 的用法
- Vue 项目开发配套工具讲解
- VueCLI 的使用和单文件组件
- 使用单文件组件编写 TodoList
- Vue-Router 路由的理解和使用
- VueX 的语法详解
- CompositionAPI 中如何使用 VueX
- 使用 axios 发送ajax 请求
- Vue3.0(正式版) + TS
- 你好 Typescript: 进入类型的世界
- 什么是 Typescript
- 为什么要学习 Typescript
- 安装 Typescript
- 原始数据类型和 Any 类型
- 数组和元组
- Interface- 接口初探
- 函数
- 类型推论 联合类型和 类型断言
- class - 类 初次见面
- 类和接口 - 完美搭档
- 枚举(Enum)
- 泛型(Generics) 第一部分
- 泛型(Generics) 第二部分 - 约束泛型
- 泛型第三部分 - 泛型在类和接口中的使用
- 类型别名,字面量 和 交叉类型
- 声明文件
- 内置类型
- 总结