首页 > 解决方案 > 使用 HEAD 方法和内置 Node.JS 模块的 HTTP 重定向

问题描述

我调整了这个函数来Node.js使用内置httphttps模块(基于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:
   

标签: node.jshttphttps

解决方案


推荐阅读