首页 > 解决方案 > 这个简单的 node.js 代理为什么以及如何工作?

问题描述

我在 Netlify 上有一个仅限前端的 Web 应用程序,它必须使用 OpenSubtitles.org 上的 API。尽管 OpenSubtitles.org 启用了 CORS,但有时我会遇到预检错误,所以我决定使用代理。

我在使用 Netlify 的代理功能时遇到了问题,所以我决定在 Heroku 上创建自己的代理,并将我的请求从前端发送到那里,因此这些请求将从服务器代理到 OpenSubtitles.org。

我根据在这里找到的代码提出了以下内容:

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

express()
    .use('/', function(req, res) {
        req.pipe(
            request({
                url: 'http://rest.opensubtitles.org/search' + req.url,
                headers: {
                    'User-Agent': 'TemporaryUserAgent'
                }
            })
        ).pipe(res);
    })
    .listen(process.env.PORT || 8000);

我以为我部署了这个,试试看,然后我会在它上面启用 CORS。但是我刚刚意识到它可以完美地工作而无需做任何其他事情。这怎么可能?为什么我可以从不同域上的仅前端应用程序调用它而不显式启用 CORS?

另外,如果服务器崩溃了,如何处理那里的错误?

标签: node.jsproxycors

解决方案


CORS 正在工作,因为url您请求的标头Access-Control-Allow-Origin设置为*. 由于您将该响应及其标头传送回原始res对象,因此它将启用 CORS,就好像它来自您的本地代理一样。

下面是一个更直接的示例,说明如何将请求代理到另一个站点并使用节点流完整地返回其响应。

const express = require('express')
const request = require('request')
const port = process.env.PORT || 1337

let server = express()

const proxyMiddleware = (req, res, next) => {
  let url = `https://www.google.com/${req.url}`
  let proxyRequest = request(url)

  // Pass request to proxied request url
  req.pipe(proxyRequest)

  // Respond to the original request with the response from proxyRequest
  proxyRequest.pipe(res)
}

server.use(proxyMiddleware)

server.listen(port, () => console.log(`Listening on ${port}`))

推荐阅读