說說webpack proxy工作原理?為什麼能解決跨域?

林恒發表於2024-05-15

一、是什麼

webpack proxy,即webpack提供的代理服務

基本行為就是接收客戶端傳送的請求後轉發給其他伺服器

其目的是為了便於開發者在開發模式下解決跨域問題(瀏覽器安全策略限制)

想要實現代理首先需要一箇中間伺服器,webpack中提供伺服器的工具為webpack-dev-server

webpack-dev-server

webpack-dev-serverwebpack 官方推出的一款開發工具,將自動編譯和自動重新整理瀏覽器等一系列對開發友好的功能全部整合在了一起

目的是為了提高開發者日常的開發效率,只適用在開發階段

關於配置方面,在webpack配置物件屬性中透過devServer屬性提供,如下:

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

module.exports = {
    // ...
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        port: 9000,
        proxy: {
            '/api': {
                target: 'https://api.github.com'
            }
        }
        // ...
    }
}

devServetr裡面proxy則是關於代理的配置,該屬性為物件的形式,物件中每一個屬性就是一個代理的規則匹配

屬性的名稱是需要被代理的請求路徑字首,一般為了辨別都會設定字首為/api,值為對應的代理匹配規則,對應如下:

  • target:表示的是代理到的目標地址
  • pathRewrite:預設情況下,我們的 /api-hy 也會被寫入到URL中,如果希望刪除,可以使用pathRewrite
  • secure:預設情況下不接收轉發到https的伺服器上,如果希望支援,可以設定為false
  • changeOrigin:它表示是否更新代理後請求的 headers 中host地址

二、工作原理

proxy工作原理實質上是利用http-proxy-middleware 這個http代理中介軟體,實現請求轉發給其他伺服器

舉個例子:

在開發階段,本地地址為http://localhost:3000,該瀏覽器傳送一個字首帶有/api標識的請求到服務端獲取資料,但響應這個請求的伺服器只是將請求轉發到另一臺伺服器中

const express = require('express');
const proxy = require('http-proxy-middleware');

const app = express();

app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
app.listen(3000);

// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar

三、跨域

在開發階段, webpack-dev-server 會啟動一個本地開發伺服器,所以我們的應用在開發階段是獨立執行在 localhost的一個埠上,而後端服務又是執行在另外一個地址上

所以在開發階段中,由於瀏覽器同源策略的原因,當本地訪問後端就會出現跨域請求的問題

透過設定webpack proxy實現代理請求後,相當於瀏覽器與服務端中新增一個代理者

當本地傳送請求的時候,代理伺服器響應該請求,並將請求轉發到目標伺服器,目標伺服器響應資料後再將資料返回給代理伺服器,最終再由代理伺服器將資料響應給本地

在代理伺服器傳遞資料給本地瀏覽器的過程中,兩者同源,並不存在跨域行為,這時候瀏覽器就能正常接收資料

注意:伺服器與伺服器之間請求資料並不會存在跨域行為,跨域行為是瀏覽器安全策略限制

參考文獻

  • https://webpack.docschina.org/configuration/dev-server/#devserverproxy

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。

說說webpack proxy工作原理?為什麼能解決跨域?

相關文章