使用webpack-dev-server設置反向代理解決前端跨域問題


webpack-dev-server是一個小型的Node.js Express服務器,它使用webpack-dev-middleware來服務於webpack的包,除此自外,它還有一個通過Sock.js來連接到服務器的微型運行時.

我們來看一下下面的配置文件(webpack.config.js)

var path = require("path");
module.exports = {
    entry:{
    app:["./app/main.js"]
    },
    output:{
    path:path.resolve(__dirname,"build"),
    publicPath:"/assets/",
    filename:"bundle.js"
}
}

  

這里你將你的源文件放在app文件夾下,並通過webpack將其打包到build文件夾下的bundle.js中.

注意:webpack-dev-server是一個獨立的NPM包,你可以通過npm install webpack-dev-server來安裝它.

基本目錄

webpack-dev-server默認會以當前目錄為基本目錄,除非你制定它.

webpack-dev-server --content-base build/

  

上述命令是在命令行中執行的,它將build目錄作為根目錄.有一點需要注意的是:webpack-dev-server生成的包並沒有放在你的真實目錄中,而是放在了內存中.

我們在基本目錄下新建一個index.html文件,然后在瀏覽器中輸入http://localhost:8080訪問.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <script src="assets/bundle.js"></script>
</body>
</html>

  

webpack-dev-server啟動proxy代理

代理配置

webpack-dev-server使用http-proxy-middleware去把請求代理到一個外部的服務器,配置的樣例如下:

//配置服務器
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        contentBase: "./app",
        port: 8090,
        proxy: {
            "/api": {
              target: 'http://localhost:8888',
              pathRewrite: {'^/api' : ''},
              changeOrigin: true
            }
        },
       
    },

  

這種代理在很多情況下是很重要的,比如你可以把一些靜態文件通過本地的服務器加載,而一些API請求全部通過一個遠程的服務器來完成。還有一個情景就是在兩個獨立的服務器之間進行請求分割,如一個服務器負責授權而另外一個服務應用本身。

pathRewrite: 對於代理的請求可以通過提供一個函數來重寫,這個函數可以查看或者改變http請求。下面的例子就會重寫HTTP請求,其主要作用就是移除URL前面的/api部分。

繞開代理

通過一個函數的返回值可以視情況的繞開一個代理。這個函數可以查看http請求和響應以及一些代理的選項。它必須返回要么是false要么是一個URL的path,這個path將會用於處理請求而不是使用原來代理的方式完成。下面的例子的配置將會忽略來自於瀏覽器的HTTP請求,他和historyApiFallback配置類似。瀏覽器請求可以像往常一樣接收到HTML文件,但是API請求將會被代理到另外的服務器:

proxy: {
  '/some/path': {
    target: 'https://other-server.example.com',
    secure: false,
    bypass: function(req, res, proxyOptions) {
      if (req.headers.accept.indexOf('html') !== -1) {
        console.log('Skipping proxy for browser request.');
        return '/index.html';
    }
  }
 }
}

 

代理本地虛擬主機

http-proxy-middleware會預解析本地hostname成為localhost,你可以使用下面的配置來修改這種默認行為:

var server = new webpackDevServer(compiler, {
  quiet: false,
  stats: { colors: true },
  proxy: {
    "/api": {
      "target": {
        "host": "action-js.dev",
        "protocol": 'http:',
        "port": 80
      },
      ignorePath: true,
      changeOrigin: true,
      secure: false
    }
  }
});
server.listen(8080);

  

貼入我自己項目的webpack.config.js配置:

var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin'); //抽取CSS文件插件
var OpenBrowserPlugin = require('open-browser-webpack-plugin'); //自動打開瀏覽器插件
var ROOT_PATH = path.resolve(__dirname);
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');
var APP_PATH = path.resolve(ROOT_PATH, 'app');

module.exports = {
    //配置服務器
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        contentBase: "./app",
        port: 8090,
        proxy: {
            "/api": {
              target: 'http://localhost:8888',
              pathRewrite: {'^/api' : ''},
              changeOrigin: true
            }
        },
       
    },

    //配置入口, 支持多入口
    entry: {
        page: ROOT_PATH + '/app/src/router/router.jsx',
        vendors: ['react', 'react-dom', 'react-router', 'mobx']  //第三方庫和框架
    },

    output: {
        // path: "dist",
        publicPath: 'dist',
        filename: 'js/bundle.js'
    },

    module: {
        loaders: [
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })//此處不用loader,改為use
            },
            {
                test: /\.less$/,
                loader: ExtractTextPlugin.extract('css-loader!less-loader')
            },
            {
                test: /\.js[x]?$/,
                exclude: /node_modules/,
                loader: 'babel-loader'
            },
            { 
                test: /\.(png|jpg)$/,
                loader: 'url-loader?limit=8192&name=img/[name].[ext]'
            },
            { 
                test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
                loader: 'url-loader'
            }
        ]
    },

    resolve: {
        extensions: [' ', '.js', '.jsx']
    },

    plugins: [
        new webpack.optimize.CommonsChunkPlugin({ 'name': 'vendors', 'filename': 'js/vendors.js' }),
        new ExtractTextPlugin("css/bundle.css"),
        // 如需jquery請解鎖
        // new webpack.ProvidePlugin({ $: "jquery" }),
        new webpack.HotModuleReplacementPlugin(),
        new OpenBrowserPlugin({ url: 'http://localhost:8090/gallery' })
    ]
}

  

總結: 如有疑問請參考官方文檔 https://doc.webpack-china.org/concepts/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM