avatar

目录
webpack 解决跨域问题

跨域问题基于浏览器的同源策略,即协议,域名,端口都一致浏览器才能发送请求,而服务端发送请求没有跨域的问题

使用 webpack 进行开发解决跨域问题主要有以下方法:

通过配置服务器代理

不能操控后端代码时(比如前后端联调)可用

在配置文件 webpack.config.js 中添加 devServer 配置,然后配置它的 proxy 属性,webpack-dev-server 在起服务后,会把匹配的本地请求转到 proxy 里配置的服务器上去请求,通过服务端的转发,实现跨域

例如:

  • 前端服务端口(dev-server)8080
  • 联调的后端端口:3000

如果在前端发送请求xhr.open('GET', '/api/user')实际上完整的请求 url 是 http://localhost:8080/api/user,直接请求报错,因为前端服务端口没有这个接口

现在给 devServer 配置 proxy

javascript
devServer: {
proxy: {'api':'http://localhost:3000'}
}

通过 webpack-dev-server 起服务器, 在遇到 /api/user 这种以 /api 开头的请求的时候,它不再往本地 localhost:8080发了,而是向对应的http://localhost:3000发请求。这是一种后端而非浏览器的的请求转发,有跨域问题。这个时候,虽然在浏览器查看前端发的请求地址是http://localhost:8080/api/user,但其实它的背后真正获取响应的请求是http://localhost:3000/api/user

实际后端接口没有类似 api 这种统一前缀,为了方便配置,proxy 提供了 pathRewrite参数改写请求路径

javascript
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: {
'/api': ''
}
}
}
}

此时前端发送请求xhr.open('GET','/api/user')

前端请求的完整 url http://localhost:3000/api/user

经过代理后最终请求 url http://localhost:3000/user

在 dev-server 内 mock 数据

直接使用 webapck-dev-server mock 数据,mock 接口和前端符合同源策略

webpack-dev-server 内部其实是自己起了一个express来做服务

webpack 的 devServer 配置提供了一个before方法,在启动服务之前,这个方法会被执行,我们可以把我们 mock 数据的逻辑写在这里

javascript
devServer: {
before(app){
app.get('/api/user',(req, res)=>{
res.json({name: 'wangyi'})
})
}
}

before 方法会传一个参数 app 供我们使用,这个参数就是 webpack-dev-server 内部起的express对象

在服务端启动 webpack

提供接口的服务端代码:

javascript
// server.js
let express = require('express')
let app = express()

app.get('/user',(req, res)=>{
res.json({name: 'webpack wangyi123'})
})
app.listen(3000)

把 webpack 构建放在服务端 server.js 中,服务器和前端共用一个地址;

通过服务端起 webpack 需要中间件 webpack-dev-middleware,整体逻辑为:

获取 webpack 模块 -> 获取 webpack 配置文件 -> 将配置文件传给 webpack 执行,获得compiler 实例 -> 把 compiler 实例传给 webpack-dev-middleware 中间件,然后整个交给express 作为 express 中间件执行 -> done

Javascript
// server.js
let webapck = require('webpack')
let config = require('./webpack.config.js')
let compiler = webapck(config)
let middle = require('webpack-dev-middleware')

let express = require('express')
let app = express()

app.use(middle(compiler))
app.get('/api/user',(req, res)=>{
res.json({name: 'wangyi123'})
})
app.listen(3000,()=>{
console.log('server is on 3000')
})

此时通过 node server.js起服务器和 webpack 前端构建

总结

第一种方法是我们提倡的跨域配置,配置代理,首选推荐

第二和第三种方法其实是在你能控制后端工程的情况下,把前后端工程合并成一个工程了,区别是第二种方法相当于把后端接口移到前端工程来起,第三种方法是把前端工程构建移到后端工程来起。

参考

webpack解决跨域的几种方法

文章作者: GRIT
文章链接: https://grit0821.github.io/Blog/2020/02/01/webpack-%E8%A7%A3%E5%86%B3%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Grit's World