node.js - 使用 HEAD 方法和内置 Node.JS 模块的 HTTP 重定向
问题描述
我调整了这个函数来Node.js
使用内置http
或https
模块(基于URL
)获得重定向的 uri:
function hasHeader(header, headers) {
var headers = Object.keys(headers)
, lheaders = headers.map(function (h) { return h.toLowerCase() })
;
header = header.toLowerCase()
for (var i = 0; i < lheaders.length; i++) {
if (lheaders[i] === header) return headers[i]
}
return false
}//hasHeader
function redirect_resolve(url, resolve, reject) {
var q = new URL(url);
var protocol = (q.protocol == "http") ? require('http') : require('https');
let options = {
path: q.pathname,
host: q.hostname,
port: q.port,
protocol: q.protocol,
method: 'HEAD'
};
// protocol.get(url, (res) => { // this works
protocol.request(options, (res) => { // this one hangs...
if (res.statusCode >= 300 && res.statusCode < 400 && hasHeader('location', res.headers)) {
return redirect_resolve(res.headers.location, resolve, reject)
}
res.on("data", (_) => { // LP: required to fire "end"
});
res.on("end", () => {
return resolve({
status_code: res.statusCode,
uri: url
});
});
}).end();
}//redirect
async function redirect(url) {
return new Promise((resolve, reject) => redirect_resolve(url, resolve, reject));
}
使用更简单的版本protocol.get
工作,而使用protocol.request(options)
它挂起:
for (const uri of uris) {
try {
var res = await redirect(uri);
console.log("URL: [%s]\nREDIRECTED: [%s]\nstatus_code: %d\n", uri, res.uri, res.status_code);
} catch (error) {
console.error(error);
}
}
使用时此代码将返回错误protocol.request
:
events.js:352
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED xxx.xxx.xxx.xxx:443
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1148:16)
Emitted 'error' event on ClientRequest instance at: