node-http-proxy如何解析目标url?
How does node-http-proxy parse the target url?
我 运行 遇到了问题,我觉得 node-http-proxy
正在改变我的目标链接。我在下面有几个例子。
我正在使用 express 作为我的服务器并使用 Metaweather API .
问题是我能够从下面的端点获取数据
https://www.metaweather.com/api/location/2487956/
https://www.metaweather.com/api/location/2487956/2013/4/30/
但是当我尝试从 https://www.metaweather.com/api/location/search/?lattlong=36.96,-122.02
调用 API
它失败了,状态码为 500,我认为 node-http-proxy
在 122.02
之后添加了一些值,因为它没有用 /
关闭
server.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);
});
感谢您调查这个问题。
我已经在 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/
我 运行 遇到了问题,我觉得 node-http-proxy
正在改变我的目标链接。我在下面有几个例子。
我正在使用 express 作为我的服务器并使用 Metaweather API .
问题是我能够从下面的端点获取数据 https://www.metaweather.com/api/location/2487956/ https://www.metaweather.com/api/location/2487956/2013/4/30/
但是当我尝试从 https://www.metaweather.com/api/location/search/?lattlong=36.96,-122.02
调用 API它失败了,状态码为 500,我认为 node-http-proxy
在 122.02
之后添加了一些值,因为它没有用 /
server.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);
});
感谢您调查这个问题。
我已经在 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/