webpack解决跨域问题

1,082 阅读1分钟

实际开发过程中,跨域问题是一个老生常谈的问题了,从webpack角度出发可提供以下三种解决方案。话不多说,直接上干货

proxy代理

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
  mode: 'development',
  devServer: {
    port: 3000,
    hot: true,
    open: true,
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    proxy: {
      '/api': {
        target: 'http://localhost:8888',
        pathRewrite: { '^/api': '' },
      },
    },
  },
  entry: './src/index.js',
  output: {
    filename: '[name][hash:8].js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
      },
    ],
  },

  resolve: {
    extensions: ['.jsx', '.mjs', '.js', '.json'],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
    }),
    new CleanWebpackPlugin(),
  ],
}

如上配置,所有客户端“/api”的请求都会呗代理到“http://localhost:8888”,并且通过pathRewrite替换掉“/api”

Tips:

  • 多个代理目标可以使用context: [];
  • 隐藏主机头信息,changeOrigin: true;
  • 默认情况下不会代理对 root 的请求,有需要时把 devServer.index 选项指定为虚假值''

devServer mock

使用devServer.before拦截所有请求,前端模拟服务端返回

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
  mode: 'development',
  devServer: {
    port: 3000,
    hot: true,
    open: true,
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    before(app) {
      app.get('/api/user', function(req, res) {
        res.json({text: 'aibfk'})
        res.end()
      })
    }
  },
  entry: './src/index.js',
  output: {
    filename: '[name][hash:8].js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
      },
    ],
  },

  resolve: {
    extensions: ['.jsx', '.mjs', '.js', '.json'],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
    }),
    new CleanWebpackPlugin(),
  ],
}

before在所有中间件之前执行,参数app相当于express的app

服务端执行webpack

服务端拿到webpack配置,进行编译执行,此时相当于前端和服务端部署在同一个服务器上,且端口同服务端端口,webpack不用再关心devServer

要实现服务端执行webpack,需要借助webpack-dev-middleware

$ yarn add webpack-dev-middleware -D

server.js

const express = require('express')
const webpack = require('webpack')
const devMiddleWare = require('webpack-dev-middleware')

const app = express()

const config = require('./webpack.config.js')
const compiler = webpack(config)

app.use(devMiddleWare(compiler))

app.get('/user', (req, res) => {
  res.json({name: 'user', age: 2000})
  res.end()
})
app.listen(8888)
console.log('server running 8888');

然后启动服务,http://localhost:8888 可以访问到前端应用,并且不存在跨域问题,相当于绕开了前后端跨域的问题

除了webpack,还有很多解决跨域的方法,如nginx/docker中间代理,jsonp,cors等,有兴趣可以一起讨论!!!