http-proxy-middleware外掛解決開發中跨域、鑑權、圖片防盜鏈問題

乘風gg發表於2019-03-06

普及一下這個外掛的一些日常使用方法,不講解非常基礎api,請搭配官方文件觀看

先說說這個外掛是幹嘛的吧。

The one-liner node.js http-proxy middleware for connect, express and browser-sync

Node.js proxying made simple. Configure proxy middleware with ease for connect, express, browser-sync and many more.

Powered by the popular Nodejitsu http-proxy.

我的理解,就是一箇中介軟體,是http-proxy的封裝,能給express,connect browser-sync等使用。

最常用在什麼地方?

用來跨域的,例如跟webpack-dev-server配合使用是現在最流行的吧,vue react等一些腳手架工具中也已經整合了,所以你配置幾行程式碼,就能跨域了。

proxyTable: {
    '/api': {
        target: 'http://localhost:3000',// 後端真實介面地址
        changeOrigin: true,
    }
},
複製程式碼

發出去的正常請求呢就是

'http://localhost:8000/api/users/info'
複製程式碼

pathRewrite的作用

但是,我們知道,公司內部的很多介面,不是api開頭的,直接users,classify,top等開頭,不可能寫很多匹配規則吧,那怎麼辦,pathRewrite可以隨意修改路徑,匹配api,然後變成空。

proxyTable: {
    '/api': {
            target: 'http://localhost:3000', // 後端真實介面地址
            changeOrigin: true,
            pathRewrite: {
           '^/api': '/api' //重寫,
        }
    }
},
複製程式碼

真實請求介面。

"http://localhost:3000/users/info"
複製程式碼

router的作用

可以理解就是重寫target,但是注意的是,但使用時一定要帶上http://的一個完整url地址

使用

axios.get('http://localhost:3000/rest/books/123') -> http://localhost:3000/rest/books/123 //攜帶http頭
複製程式碼

配置

const routers = {
    '/rest': 'http://localhost:30001' 
};
const proxyTable = {
  '/api': {
    target: 'http://localhost:3000',
    changeOrigin: true,
    logLevel: 'debug',
    pathRewrite: {
      '^/api': ''
    },
    router: routers
  }
};
複製程式碼

為什麼我推薦用攜帶http://開頭的完整路徑呢,因為當傳送出去的請求地址,同時匹配'/api' '/rest'的時候,其實也會去rest的那個伺服器地址下,容易混淆,下面請看。

http-proxy-middleware外掛解決開發中跨域、鑑權、圖片防盜鏈問題

鑑權

如果只想簡單的驗證介面是否需要token,或者我們在用一些收費介面的時候,總需要攜帶一些token,可以這麼做。

proxy: {
    '/mmbiz_png': {
        target: 'https://mmbiz.qpic.cn',
        changeOrigin: true,

        headers: {
            token: 'token'
        }
    }
複製程式碼

referer防盜鏈

有時候一些引用第三方的圖片會破圖的現象,可以用這種辦法。

http-proxy-middleware外掛解決開發中跨域、鑑權、圖片防盜鏈問題

這裡有點麻煩的就是,我們不能直接用img標籤去渲染一個src的線上地址,我們得用axios等ajax庫去把圖片二進位制流請求回來,然後通過URL.createObjectURL介面生成一個url

axios
  .get(
    '/mmbiz_png/微信圖片
  )
  .then(({data}) => {
    var img = document.createElement('img')
    var url = window.URL.createObjectURL(data)
    img.src = objectUrl
    img.onload = () => {
      window.URL.revokeObjectURL(url)
    }
    document.body.appendChild(img)
  })
複製程式碼
proxy: {
    '/mmbiz_png': {
        target: 'https://mmbiz.qpic.cn',
        changeOrigin: true,
        headers: {
            referer: '' //測試了,可加可不加,加上最好。
        }
    }
複製程式碼

onProxyRes(cookie跨域的場景)

還有一個業務場景就是,當我們本地除錯測試或者線上程式碼的時候,會因為後端cookie設定了一些secure domain等安全策略,而導致本地開發環境cookie寫不進去。這是因為由於同源策略的限制,所讀取的cookie為跨域請求介面所在域的cookie,而非當前頁。如果想實現當前頁cookie的寫入,則用以下辦法。

雖然官方文件有說可以用cookieDomainRewrite 和cookiePathRewrite來搭配,但是曾經看到一種挺好的辦法。

proxy: {
    '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        pathRewrite: {
            '^/api': ''
        },
        headers: {
            referer: '' //
        },
        onProxyRes(proxyRes) {
            const key = 'set-cookie';
            if (proxyRes.headers[key]) {
                const cookies = proxyRes.headers[key].join('').split(' ');
                // 切割掉一些嚴格的安全校驗,只保留了第一項和Path,這樣secure、domain都被忽略了。
                proxyRes.headers[key] = [cookies[0], 'Path=/'].join(' ');
            }
        }
    }

複製程式碼

值得一提的是,axios等ajax庫,得配置withCredentials

websocket

加多一個就好 ws: true

額外的

在一些spa + node.js + 後端架構的專案裡,或者一些ssr專案上,這個外掛也可以在express中使用,如果你自己不想寫代理伺服器的話。


var express = require('express')
var proxy = require('../../index') // require('http-proxy-middleware');


var option = proxy({
  target: 'www.xxx.com',
  changeOrigin: true,
  logLevel: 'debug'
})

var app = express()

app.use('/api', option)

app.listen(3000)

複製程式碼

更多

點選檢視

http-proxy-middleware外掛解決開發中跨域、鑑權、圖片防盜鏈問題

參考

基本用法

demo

相關文章