1. 程式人生 > >全棧07 Express轉發前端請求實現跨域

全棧07 Express轉發前端請求實現跨域

http模組和https模組

使用了express的http模組實現了對前端http請求的簡單轉發,從而實現了跨域請求

const express = require('express');
const http = require('http');

const router = express.Router();

router.route('/')
  .get((req, res) => {
    const { url } = req.query;

    const proxyReq = http.request(url, remoteRes => remoteRes.pipe(res));

    proxyReq.end();
  });

module.exports = router;

router.use('/proxy', proxy);

使用的時候:

export const QUERY_URL = 'https://wallstreetcn.com/live/global';
const X_URL = `/api/proxy?url=${encodeURIComponent(QUERY_URL)}`;

fetch(X_URL).then(v => console.log(v.text()))

但是這樣有一個問題,如果請求的資源型別為頁面資源(文字),如果是經過gzip壓縮的,直接處理會返回亂碼,需要使用zlib.createGunzip()方法進行解壓縮處理後再進行轉發就可以了

const express = require('express');
const http = require('http');
const zlib = require('zlib');

const router = express.Router();

router.route('/')
  .get((req, res) => {
    const { url } = req.query;

    const proxyReq = request(url, (remoteRes) => {
      if (remoteRes.headers['content-encoding'] === 'gzip') {
        const gzip = zlib.createGunzip();
        return remoteRes.pipe(gzip).pipe(res);
      }
      return remoteRes.pipe(res);
    });

    proxyReq.end();
  });

module.exports = router;

router.use('/proxy', proxy);

request模組

但是還有一個問題,這樣的轉發只支援http請求的轉發,而不支援https的轉發,如果要修改就需要根據傳遞進來的url來確定使用http模組還是https模組

其實有更簡單的方式,那就是使用request模組

它支援http和https請求,簡單的使用可以參考這篇文章

實現轉發的的時候,也使用pipe來進行轉發:

var request = require('request');

app.use('/api', function(req, res) {
  var url = apiUrl + req.url;
  req.pipe(request(url)).pipe(res);
});

上面完整的請求傳遞給API,並且將相應傳遞給請求的發起者,支援GET/PUT/DELETE的其他請求方式

回到我們的例子中,使用request模組使程式碼大大簡化

const express = require('express');
const request = require('request');

const router = express.Router();

router.route('/')
  .get((req, res) => {
    const { url } = req.query;
    req.pipe(request(url)).pipe(res);
  });

module.exports = router;

router.use('/proxy', proxy);

request也不需要對gzip進行解壓,資料直接可用。

也可以對headers進行設定:

router.route('/')
  .get((req, res) => {
    const { url } = req.query;

    const options = {
      url,
      headers: {
        accept: req.headers.accept,
      },
    };
    req.pipe(request(options)).pipe(res);
  });

module.exports = router;

參考