Как node-http-proxy анализирует целевой URL?

Я столкнулся с проблемой и чувствую, что node-http-proxy меняет мои целевые ссылки. У меня есть несколько примеров ниже.

Я использую экспресс в качестве своего сервера и использую API Metaweather.

Проблема в том, что мне удалось получить данные с конечных точек ниже https://www.metaweather.com/api/location/2487956/ https://www.metaweather.com/api/location/2487956/2013/4/30/

Но когда я пытаюсь вызвать API из https://www.metaweather.com/api/location/search/?lattlong=36.96,-122.02

Он не работает с кодом состояния 500, из-за чего я думаю, что node-http-proxy добавил некоторые значения после 122.02, поскольку он не был закрыт с помощью /

сервер.js

const express = require("express");
const next = require("next");
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

const httpProxy = require("http-proxy");

const proxyOptions = {
  changeOrigin: true
};

const apiProxy = httpProxy.createProxyServer(proxyOptions);

const apiUrl =
  "https://www.metaweather.com/api/location/search/?lattlong=36.96,-122.02";

/*
https://www.metaweather.com/api/location/search/?lattlong=36.96,-122.02 - failed with 500
https://www.metaweather.com/api/location/2487956/ - passed
https://www.metaweather.com/api/location/2487956/2013/4/30/ - passed
*/

app
  .prepare()
  .then(() => {
    const server = express();

    server.use("/api", (req, res) => {
      console.log("Going to call this API " + apiUrl);
      apiProxy.web(req, res, { target: apiUrl });
    });

    server.get("*", (req, res) => {
      return handle(req, res);
    });

    server.listen(3000, err => {
      if (err) throw err;
      console.log("> Ready on http://localhost:3000");
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

Спасибо за изучение этого вопроса.


person Community    schedule 02.03.2018    source источник


Ответы (1)


Я воспроизвел, где это происходит в node-http-proxy.

В common.js есть функция urlJoin, которая добавляет req.url в конец целевого URL.

Я не совсем уверен, каково намерение, но это начало.

Вот мой тест:

const urlJoin = function() {
  //
  // We do not want to mess with the query string. All we want to touch is the path.
  //
var args = Array.prototype.slice.call(arguments),
    lastIndex = args.length - 1,
    last = args[lastIndex],
    lastSegs = last.split('?'),
    retSegs;

args[lastIndex] = lastSegs.shift();

//
// Join all strings, but remove empty strings so we don't get extra slashes from
// joining e.g. ['', 'am']
//
retSegs = [
  args.filter(Boolean).join('/')
      .replace(/\/+/g, '/')
      .replace('http:/', 'http://')
      .replace('https:/', 'https://')
];

// Only join the query string if it exists so we don't have trailing a '?'
// on every request

// Handle case where there could be multiple ? in the URL.
retSegs.push.apply(retSegs, lastSegs);

return retSegs.join('?')
};

let path = urlJoin('/api/location/search/?lattlong=36.96,-122.02', '/');

console.log(path);
//                 /api/location/search/?lattlong=36.96,-122.02/
person thomann061    schedule 02.03.2018