你如何在Node.js中遵循HTTP重定向?

Zac*_*ach 70 http-redirect node.js

我想在节点中打开一个页面并处理我的应用程序中的内容.像这样的东西似乎运作良好:

var opts = {host: host, path:pathname, port: 80};
http.get(opts, function(res) {
  var page = '';
  res.on('data', function (chunk) {
    page += chunk;
  });
  res.on('end', function() {
     // process page
  });
Run Code Online (Sandbox Code Playgroud)

但是,如果页面返回301/302重定向,则不起作用.如果有多个重定向,我将如何以可重用的方式执行此操作?在http之上是否有一个包装器模块可以更轻松地处理来自节点应用程序的http响应?

Oli*_*nde 94

如果您只想遵循重定向但仍希望使用内置的HTTP和HTTPS模块,我建议您使用https://github.com/follow-redirects/follow-redirects.

yarn add follow-redirects
npm install follow-redirects
Run Code Online (Sandbox Code Playgroud)

您需要做的就是更换:

var http = require('http');
Run Code Online (Sandbox Code Playgroud)

var http = require('follow-redirects').http;
Run Code Online (Sandbox Code Playgroud)

...并且您的所有请求都将自动遵循重定向.

披露:我写了这个模块.

  • 这比接受的以“request”为特色的答案要好得多,后者会为您的模块添加 20 多个新的依赖项来完成这样一个简单的任务。感谢您保持 npm 模块的轻量级,Oliver!:) (4认同)

Ray*_*nos 46

在http之上是否有一个包装器模块可以更轻松地处理来自节点应用程序的http响应?

request

请求中的重定向逻辑

  • 为什么生活b'jesus不是内置http模块的这一部分?! (13认同)
  • @Raynos,内置`http`模块的request()方法不遵循重定向,因此这不是内置`http`模块的一部分. (9认同)
  • “请求”已被弃用。 (9认同)
  • 是否有可能以某种方式为每个重定向进行回调?我想存储请求通过的每个URL.无法在文档中找到它. (3认同)
  • 这是。它被称为`http.request`,API 非常简单。 (2认同)

sko*_*ozz 28

更新:

现在,您可以var request = require('request');使用followAllRedirectsparam 跟踪所有重定向.

request({
  followAllRedirects: true,
  url: url
}, function (error, response, body) {
  if (!error) {
    console.log(response);
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 你不能简单地要求('请求'),这是一个外部模块,需要先下载和安装 - https://www.npmjs.com/package/request(npm安装请求) (7认同)
  • “请求”已被弃用 (3认同)

Nak*_*lon 12

使基于另一个要求response.headers.location:

      const request = function(url) {
        lib.get(url, (response) => {
          var body = [];
          if (response.statusCode == 302) {
            body = [];
            request(response.headers.location);
          } else {
            response.on("data", /*...*/);
            response.on("end", /*...*/);
          };
        } ).on("error", /*...*/);
      };
      request(url);
Run Code Online (Sandbox Code Playgroud)


wie*_*son 11

这是我使用普通节点下载 JSON 的(递归)方法,不需要任何包。

import https from "https";

function get(url, resolve, reject) {
  https.get(url, (res) => {
    // if any other status codes are returned, those needed to be added here
    if(res.statusCode === 301 || res.statusCode === 302) {
      return get(res.headers.location, resolve, reject)
    }

    let body = [];

    res.on("data", (chunk) => {
      body.push(chunk);
    });

    res.on("end", () => {
      try {
        // remove JSON.parse(...) for plain data
        resolve(JSON.parse(Buffer.concat(body).toString()));
      } catch (err) {
        reject(err);
      }
    });
  });
}

async function getData(url) {
  return new Promise((resolve, reject) => get(url, resolve, reject));
}

// call
getData("some-url-with-redirect").then((r) => console.log(r));

Run Code Online (Sandbox Code Playgroud)


jcu*_*bic 6

这是我用来获取具有重定向的 url 的函数:

const http = require('http');
const url = require('url');

function get({path, host}, callback) {
    http.get({
        path,
        host
    }, function(response) {
        if (response.headers.location) {    
            var loc = response.headers.location;
            if (loc.match(/^http/)) {
                loc = new Url(loc);
                host = loc.host;
                path = loc.path;
            } else {
                path = loc;
            }
            get({host, path}, callback);
        } else {
            callback(response);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

它的工作原理与 http.get 相同,但遵循重定向。