request 简化的 HTTP 客户端

发布于 2021-08-04 21:19:27 字数 48431 浏览 1654 评论 0

超级简单易用

请求被设计为进行 http 调用的最简单方法。它支持 HTTPS,默认情况下遵循重定向。

const request = require('request');
request('http://www.google.com', function (error, response, body) {
  console.error('error:', error); // Print the error if one occurred
  console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
  console.log('body:', body); // Print the HTML for the Google homepage.
});

Request 还提供了诸如 和的 便捷方法,并且有许多 使用示例 和几种 调试技术。request.defaultsrequest.post


流媒体

您可以将任何响应流到文件流。

request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))

您还可以将文件流式传输到 PUT 或 POST 请求。此方法还将根据文件扩展名到内容类型的映射(在这种情况下application/json)检查文件扩展名,并content-type在PUT请求中使用正确的名称(如果标头尚未提供)。

fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))

请求也 pipe 可以自己处理。这样做时,content-typecontent-length 保留在PUT标头中。

request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))

收到响应后,请求将发出“响应”事件。该 response 参数将是 http.IncomingMessage 的实例。

request
  .get('http://google.com/img.png')
  .on('response', function(response) {
    console.log(response.statusCode) // 200
    console.log(response.headers['content-type']) // 'image/png'
  })
  .pipe(request.put('http://mysite.com/img.png'))

为了在处理流请求时轻松处理错误,请error在管道传输之前侦听事件:

request
  .get('http://mysite.com/doodle.png')
  .on('error', function(err) {
    console.error(err)
  })
  .pipe(fs.createWriteStream('doodle.png'))

现在让我们开始幻想。

http.createServer(function (req, resp) {
  if (req.url === '/doodle.png') {
    if (req.method === 'PUT') {
      req.pipe(request.put('http://mysite.com/doodle.png'))
    } else if (req.method === 'GET' || req.method === 'HEAD') {
      request.get('http://mysite.com/doodle.png').pipe(resp)
    }
  }
})

您还可以pipe()http.ServerRequest实例,也可以到http.ServerResponse实例。将发送HTTP方法,标头和实体数据。这意味着,如果您不太在意安全性,则可以执行以下操作:

http.createServer(function (req, resp) {
  if (req.url === '/doodle.png') {
    const x = request('http://mysite.com/doodle.png')
    req.pipe(x)
    x.pipe(resp)
  }
})

并且由于pipe()返回≥0.5.x节点中的目标流,因此您可以执行一行代理。:)

req.pipe(request('http://mysite.com/doodle.png')).pipe(resp)

而且,这些新功能都不会与请求以前的功能发生冲突,只会扩展它们。

const r = request.defaults({'proxy':'http://localproxy.com'})

http.createServer(function (req, resp) {
  if (req.url === '/doodle.png') {
    r.get('http://google.com/doodle.png').pipe(resp)
  }
})

您仍然可以使用中间代理,请求仍将遵循HTTP转发等。


Promises & Async/Await

request 本机支持流和回调接口。如果您想request返回一个Promise,则可以使用替代接口包装request。如果您更喜欢使用Promises,或者您想在ES2017中使用async/ await,这些包装器将非常有用。
请求团队提供了几种替代接口,包括:

另外,util.promisifyNode.js v8.0中提供的可以用来转换一个常规函数,该函数接受回调以返回诺言。


形式

request支持application/x-www-form-urlencodedmultipart/form-data上传表格。有关multipart/related参考multipartAPI。

application / x-www-form-urlencoded(URL-Encoded Forms)

URL编码的表单很简单。

request.post('http://service.com/upload', {form:{key:'value'}})
// or
request.post('http://service.com/upload').form({key:'value'})
// or
request.post({url:'http://service.com/upload', form: {key:'value'}}, function(err,httpResponse,body){ /* ... */ })

多部分/表单数据(多部分表单上传)

对于multipart/form-data我们使用表单数据的库@felixge。在大多数情况下,您可以通过formData选项传递上传表单数据。

const formData = {
  // Pass a simple key-value pair
  my_field: 'my_value',
  // Pass data via Buffers
  my_buffer: Buffer.from([1, 2, 3]),
  // Pass data via Streams
  my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
  // Pass multiple values /w an Array
  attachments: [
    fs.createReadStream(__dirname + '/attachment1.jpg'),
    fs.createReadStream(__dirname + '/attachment2.jpg')
  ],
  // Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
  // Use case: for some types of streams, you'll need to provide "file"-related information manually.
  // See the `form-data` README for more information about options: https://github.com/form-data/form-data
  custom_file: {
    value:  fs.createReadStream('/dev/urandom'),
    options: {
      filename: 'topsecret.jpg',
      contentType: 'image/jpeg'
    }
  }
};
request.post({url:'http://service.com/upload', formData: formData}, function optionalCallback(err, httpResponse, body) {
  if (err) {
    return console.error('upload failed:', err);
  }
  console.log('Upload successful!  Server responded with:', body);
});

对于高级情况,您可以通过访问表格数据对象本身r.form()。可以对其进行修改,直到在事件循环的下一个周期触发请求为止。(请注意,此调用form()将清除该请求的当前设置的表单数据。)

//注意:高级用例,对于正常使用,请参见
const r = request.post('http://service.com/upload', function optionalCallback(err, httpResponse, body) {...})
const form = r.form();
form.append('my_field', 'my_value');
form.append('my_buffer', Buffer.from([1, 2, 3]));
form.append('custom_file', fs.createReadStream(__dirname + '/unicycle.jpg'), {filename: 'unicycle.jpg'});

有关更多信息和示例,请参见表单数据自述文件

多部分/相关

不同HTTP实现中的某些变体在multipart/related请求边界之前,之后或之前和之后都需要换行符/ CRLF (使用multipart选项)。在.NET WebAPI 4.0版中已经观察到了这一点。您可以通过将边界preambleCRLF或postamble传递true给您的请求选项来打开它们。

  request({
    method: 'PUT',
    preambleCRLF: true,
    postambleCRLF: true,
    uri: 'http://service.com/upload',
    multipart: [
      {
        'content-type': 'application/json',
        body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
      },
      { body: 'I am an attachment' },
      { body: fs.createReadStream('image.png') }
    ],
    // alternatively pass an object containing additional options
    multipart: {
      chunked: false,
      data: [
        {
          'content-type': 'application/json',
          body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
        },
        { body: 'I am an attachment' }
      ]
    }
  },
  function (error, response, body) {
    if (error) {
      return console.error('upload failed:', error);
    }
    console.log('Upload successful!  Server responded with:', body);
  })

HTTP认证

request.get('http://some.server.com/').auth('username', 'password', false);
// or
request.get('http://some.server.com/', {
  'auth': {
    'user': 'username',
    'pass': 'password',
    'sendImmediately': false
  }
});
// or
request.get('http://some.server.com/').auth(null, null, true, 'bearerToken');
// or
request.get('http://some.server.com/', {
  'auth': {
    'bearer': 'bearerToken'
  }
});

如果作为选项传递,auth则应为包含值的哈希值:

  • user || username
  • pass || password
  • sendImmediately (可选的)
  • bearer (可选的)

方法表格带有参数 auth(username, password, sendImmediately, bearer)
sendImmediately默认为true,这将导致发送基本或承载身份验证标头。如果sendImmediatelyfalse,则request在接收401到服务器的响应(必须包含WWW-Authenticate指示所需认证方法的标头)后, 将使用适当的认证标头重试 。
请注意,您还可以使用URL本身指定基本身份验证,如RFC 1738中所述。只需 user:password在主持人之前通过@标志:

const username = 'username',
    password = 'password',
    url = 'http://' + username + ':' + password + '@some.server.com';

request({url}, function (error, response, body) {
   // Do more stuff with 'body' here
});

支持摘要式身份验证,但仅sendImmediately 将设置为false;否则,request将在初始请求上发送基本身份验证,这可能会导致请求失败。
支持承载身份验证,并在该bearer值可用时激活。该值可以是a StringFunction返回a String。如果与defaults允许单个功能在发送请求时提供最后一个已知令牌或即时计算一个令牌一起使用,则使用函数提供承载令牌特别有用。


自定义HTTP标头

User-Agent可以在options对象中设置HTTP标头(例如)。在下面的示例中,我们调用github API来查找请求存储库的星号和分叉数。这需要一个自定义User-Agent标头以及https。

const request = require('request');

const options = {
  url: 'https://api.github.com/repos/request/request',
  headers: {
    'User-Agent': 'request'
  }
};

function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    const info = JSON.parse(body);
    console.log(info.stargazers_count + " Stars");
    console.log(info.forks_count + " Forks");
  }
}

request(options, callback);

OAuth签名

支持OAuth 1.0版。默认签名算法为 HMAC-SHA1

// OAuth1.0 - 3-legged server side flow (Twitter example)
// step 1
const qs = require('querystring')
  , oauth =
    { callback: 'http://mysite.com/callback/'
    , consumer_key: CONSUMER_KEY
    , consumer_secret: CONSUMER_SECRET
    }
  , url = 'https://api.twitter.com/oauth/request_token'
  ;
request.post({url:url, oauth:oauth}, function (e, r, body) {
  // Ideally, you would take the body in the response
  // and construct a URL that a user clicks on (like a sign in button).
  // The verifier is only available in the response after a user has
  // verified with twitter that they are authorizing your app.

  // step 2
  const req_data = qs.parse(body)
  const uri = 'https://api.twitter.com/oauth/authenticate'
    + '?' + qs.stringify({oauth_token: req_data.oauth_token})
  // redirect the user to the authorize uri

  // step 3
  // after the user is redirected back to your server
  const auth_data = qs.parse(body)
    , oauth =
      { consumer_key: CONSUMER_KEY
      , consumer_secret: CONSUMER_SECRET
      , token: auth_data.oauth_token
      , token_secret: req_data.oauth_token_secret
      , verifier: auth_data.oauth_verifier
      }
    , url = 'https://api.twitter.com/oauth/access_token'
    ;
  request.post({url:url, oauth:oauth}, function (e, r, body) {
    // ready to make signed requests on behalf of the user
    const perm_data = qs.parse(body)
      , oauth =
        { consumer_key: CONSUMER_KEY
        , consumer_secret: CONSUMER_SECRET
        , token: perm_data.oauth_token
        , token_secret: perm_data.oauth_token_secret
        }
      , url = 'https://api.twitter.com/1.1/users/show.json'
      , qs =
        { screen_name: perm_data.screen_name
        , user_id: perm_data.user_id
        }
      ;
    request.get({url:url, oauth:oauth, qs:qs, json:true}, function (e, r, user) {
      console.log(user)
    })
  })
})

对于RSA-SHA1签名,请对OAuth选项对象进行以下更改:

  • 通过 signature_method : 'RSA-SHA1'
  • 代替consumer_secretprivate_keyPEM格式指定一个字符串

对于PLAINTEXT签名,请对OAuth选项对象进行以下更改:

  • 通过 signature_method : 'PLAINTEXT'

如 oauth1规范的“ 使用者请求参数”部分所述,通过查询参数或在帖子正文中发送OAuth参数 :

  • 通过transport_method : 'query'transport_method : 'body'进入OAuth选项对象。
  • transport_method 默认为 'header'

要使用请求正文哈希,您可以

  • 手动生成主体哈希并将其作为字符串传递 body_hash: '...'
  • 通过自动生成正文哈希 body_hash: true

代理人

如果您指定一个proxy选项,那么请求(以及所有后续重定向)将通过连接发送到代理服务器。
如果您的端点是一个httpsURL,并且使用的是代理服务器,然后请求将发送CONNECT到代理服务器的请求,第一,然后使用附带的连接来连接到端点。
也就是说,首先它将发出如下请求:

HTTP/1.1 CONNECT endpoint-server.com:80
Host: proxy-server.com
User-Agent: whatever user agent you specify

然后代理服务器endpoint-server 在端口上建立与TCP的连接80,并返回如下响应:

HTTP/1.1 200 OK

此时,连接保持打开状态,客户端直接与endpoint-server.com机器通信。
有关 更多信息,请参见HTTP隧道上的Wikipedia页面
默认情况下,代理http流量时,请求将仅发出标准代理http请求。这是通过使url 请求的初始行部分成为终结点的完全限定的url来完成的。
例如,它将发出一个类似于以下内容的请求:

HTTP/1.1 GET http://endpoint-server.com/some-url
Host: proxy-server.com
Other-Headers: all go here
request body or whatever

因为纯的“ http over http”隧道不提供其他安全性或其他功能,所以在这种情况下,使用简单的HTTP代理通常更简单。但是,如果您想强制使用隧道代理,可以将tunnel选项设置为true
您也可以http通过显式设置发出标准代理请求 tunnel : false,但是请注意,这将使代理可以查看到/来自目标服务器的流量
如果您使用的是隧道代理,则可以将设置为 proxyHeaderWhiteList与代理共享某些标头。
您还可以将设置为proxyHeaderExclusiveList仅与代理而不与目标主机共享某些标头。
默认情况下,此设置为:

accept
accept-charset
accept-encoding
accept-language
accept-ranges
cache-control
content-encoding
content-language
content-length
content-location
content-md5
content-range
content-type
connection
date
expect
max-forwards
pragma
proxy-authorization
referer
te
transfer-encoding
user-agent
via

请注意,使用隧道代理时,proxy-authorization 标头和来自custom的任何标头proxyHeaderExclusiveList不会发送到终结点服务器,而只会发送到代理服务器。

使用环境变量控制代理行为

遵守以下环境变量request

  • HTTP_PROXY / http_proxy
  • HTTPS_PROXY / https_proxy
  • NO_PROXY / no_proxy

HTTP_PROXY/ http_proxy设置,它们将被用于没有一个明确的代理非SSL请求proxy配置选项存在。同样,对于没有显式配置选项的SSL请求,将使用HTTPS_PROXY/ 。在一个环境变量中定义一个代理是有效的,但是使用配置选项针对特定请求覆盖它。此外,可以将配置选项显式设置为false / null,以完全退出该请求的代理。https_proxyproxyproxyproxy
request也知道NO_PROXY/ no_proxy环境变量。这些变量为每个主机提供了一种选择退出代理的精细方法。它应包含逗号分隔的主机列表,以选择退出代理。当使用特定的目标端口时,也可以选择代理。最后,可以将变量设置为*选择退出其他环境变量的隐式代理配置。
以下是有效值的一些示例no_proxy

  • google.com -不要将HTTP / HTTPS请求代理给Google。
  • google.com:443-不要将HTTPS请求代理给Google,而是 HTTP请求代理给Google。
  • google.com:443, yahoo.com:80 -不要将HTTPS请求代理到Google,也不要将HTTP请求代理到Yahoo !!
  • *- 完全忽略https_proxy/ http_proxy环境变量。

UNIX域套接字

request支持向UNIX域套接字发出请求。要制作一个,请使用以下URL方案:

/* Pattern */ 'http://unix:SOCKET:PATH'
/* Example */ request.get('http://unix:/absolute/path/to/unix.socket:/request/path')

注意:SOCKET假定该路径对于主机文件系统的根目录是绝对的。


TLS / SSL协议

TLS / SSL协议选项,例如certkeypassphrase,可直接在设置options对象,在agentOptions所述的属性options对象,或甚至在https.globalAgent.options。请记住,尽管agentOptions允许的配置范围稍微宽一些,但建议的方法是options直接通过对象,因为在代理环境中使用agentOptionshttps.globalAgent.options不会以相同的方式应用对象(因为数据通过TLS连接而不是通过http /传输) https代理)。

const fs = require('fs')
    , path = require('path')
    , certFile = path.resolve(__dirname, 'ssl/client.crt')
    , keyFile = path.resolve(__dirname, 'ssl/client.key')
    , caFile = path.resolve(__dirname, 'ssl/ca.cert.pem')
    , request = require('request');

const options = {
    url: 'https://api.some-server.com/',
    cert: fs.readFileSync(certFile),
    key: fs.readFileSync(keyFile),
    passphrase: 'password',
    ca: fs.readFileSync(caFile)
};

request.get(options);

使用 options.agentOptions

在下面的示例中,我们调用需要客户端SSL证书(PEM格式)和密码保护的私钥(PEM格式)的API,并禁用SSLv3协议:

const fs = require('fs')
    , path = require('path')
    , certFile = path.resolve(__dirname, 'ssl/client.crt')
    , keyFile = path.resolve(__dirname, 'ssl/client.key')
    , request = require('request');

const options = {
    url: 'https://api.some-server.com/',
    agentOptions: {
        cert: fs.readFileSync(certFile),
        key: fs.readFileSync(keyFile),
        // Or use `pfx` property replacing `cert` and `key` when using private key, certificate and CA certs in PFX or PKCS12 format:
        // pfx: fs.readFileSync(pfxFilePath),
        passphrase: 'password',
        securityOptions: 'SSL_OP_NO_SSLv3'
    }
};

request.get(options);

只能通过指定secureProtocol以下命令来强制使用SSLv3 :

request.get({
    url: 'https://api.some-server.com/',
    agentOptions: {
        secureProtocol: 'SSLv3_method'
    }
});

除了通常允许的证书颁发机构(CA)签名的证书之外,还可以接受其他证书。例如,在使用自签名证书时,这可能很有用。要必须有不同的根证书,您可以通过添加CA的证书文件的内容到指定签名CA agentOptions。域提供的证书必须由指定的根证书签名:

request.get({
    url: 'https://api.some-server.com/',
    agentOptions: {
        ca: fs.readFileSync('ca.cert.pem')
    }
});

ca如果您具有私有或内部公司公钥基础结构层次结构,则该值可以是证书的数组。例如,如果您要连接到https://api.some-server.com,它会显示一个包含以下内容的钥匙链:

  1. 它自己的公共密钥,由以下人员签名:
  2. 中间“公司发行服务器”,依次由以下人员签名:
  3. 根CA“ Corp Root CA”;

您可以按以下方式配置您的请求:

request.get({
    url: 'https://api.some-server.com/',
    agentOptions: {
        ca: [
          fs.readFileSync('Corp Issuing Server.pem'),
          fs.readFileSync('Corp Root CA.pem')
        ]
    }
});

支持HAR 1.2

options.har属性将覆盖值:urlmethodqsheadersformformDatabodyjson,以及构建多部分数据,并且当从磁盘读取的文件request.postData.params[].fileName的存在而没有匹配value
验证步骤将检查HAR请求格式是否与最新规范(v1.2)匹配,如果不匹配则跳过解析。

  const request = require('request')
  request({
    // will be ignored
    method: 'GET',
    uri: 'http://www.google.com',

    // HTTP Archive Request Object
    har: {
      url: 'http://www.mockbin.com/har',
      method: 'POST',
      headers: [
        {
          name: 'content-type',
          value: 'application/x-www-form-urlencoded'
        }
      ],
      postData: {
        mimeType: 'application/x-www-form-urlencoded',
        params: [
          {
            name: 'foo',
            value: 'bar'
          },
          {
            name: 'hello',
            value: 'world'
          }
        ]
      }
    }
  })
  // POST请求将发送到http://www.mockbin.com 
  //正文为 application/x-www-form-urlencoded 正文:
  // foo = bar&hello = world

request(options, callback)

第一个参数可以是a urloptions对象。唯一需要的选项是uri;其他所有都是可选的。

  • uri|| url-完全限定的uri或来自的解析的url对象url.parse()
  • baseUrl-完全合格的uri字符串用作基本网址。与结合使用request.defaults时最有用,例如,当您想向同一个域发出许多请求时。如果baseUrlhttps://example.com/api/,则请求/end/point?test=true将获取https://example.com/api/end/point?test=true。当baseUrl给出时,uri也必须是一个字符串。
  • method- HTTP方法(默认值:"GET"
  • headers- HTTP头(默认:{}

  • qs -包含要附加到的查询字符串值的对象 uri
  • qsParseOptions-包含用于传递给qs.parse方法的选项的对象。或者使用此格式将选项传递给querystring.parse方法{sep:';', eq:':', options:{}}
  • qsStringifyOptions-包含用于传递给qs.stringify方法的选项的对象。或者,使用此格式将选项传递给 querystring.stringify方法{sep:';', eq:':', options:{}}。例如,要更改使用qs模块将数组转换为查询字符串的arrayFormat方式,请通过以下选项之一传递选项:indices|brackets|repeat
  • useQuerystring-如果为true,则用于querystring对查询字符串进行字符串化和解析,否则使用qs(默认值:)falsetrue如果需要将数组序列化为foo=bar&foo=baz默认值,则将此选项设置 为foo[0]=bar&foo[1]=baz

  • body-用于PATCH,POST和PUT请求的实体主体。必须是BufferStringReadStream。如果jsontrue,则body必须是JSON可序列化的对象。
  • form-当传递对象或查询字符串时,它设置body为值的查询字符串表示形式,并添加Content-type: application/x-www-form-urlencoded标头。如果不传递任何选项,FormData则会返回一个实例(并通过管道传递给请求)。请参阅上面的“Forms”部分。
  • formData-传递给multipart/form-data请求的数据。请参阅 上面的“ Forms”部分。
  • multipart-包含其自己的标题和body 属性的对象数组。发送multipart/related请求。请参阅上面的“ Forms”部分。
    • 或者,您可以传入一个对象{chunked: false, data: []}, 其中chunked用于指定请求是否在非chunked请求中以分块传输编码发送,不允许有正文流的数据项。
  • preambleCRLF-在multipart/form-data请求的边界之前添加换行符/ CRLF 。
  • postambleCRLF-在multipart/form-data请求边界的末尾添加换行符/ CRLF 。
  • json-设置body为值的JSON表示并添加Content-type: application/json标头。此外,将响应主体解析为JSON。
  • jsonReviver- 解析器功能,将JSON.parse()在解析JSON响应主体时传递给它。
  • jsonReplacer- 在对JSON请求主体进行字符串化时将传递给的替换函数JSON.stringify()

  • auth-包含值user|| usernamepass|| password,和sendImmediately(可选)。请参阅上面的文档。
  • oauth-OAuth HMAC-SHA1签名的选项。请参阅上面的文档。
  • hawk-Hawk签名的选项。该credentials密钥必须包含必要的签约信息,请参阅鹰文档的详细信息
  • aws- object包含AWS签名信息。应具有属性keysecretsession(可选)(请注意,这仅适用于需要会话作为规范字符串的一部分的服务)。还需要属性bucket,除非您将其指定bucket为路径的一部分,否则请求不使用存储桶(即GET Services)。如果要使用AWS Sign版本4,请使用sign_version带有值的参数,4否则默认值为版本2。如果您使用的是SigV4,则还可以包括service用于指定服务名称的属性。注意:您需要npm install aws4先。
  • httpSignature- 使用Joyent库HTTP签名方案的选项。在和属性必须被指定。有关其他选项,请参阅文档。keyIdkey

  • followRedirect-遵循HTTP 3xx响应作为重定向(默认值:)true。此属性也可以实现为将response对象作为单个参数获取的函数,并且true如果重定向应继续进行,false否则应返回。
  • followAllRedirects-遵循非HTTP GET作为3XX重定向响应(默认值:false
  • followOriginalHttpMethod-默认情况下,我们重定向到HTTP方法GET。您可以启用这个属性重定向到原来的HTTP方法(默认:false
  • maxRedirects-重定向的最大数量跟随(默认值:10
  • removeRefererHeader-发生重定向时删除引用标头(默认值:)false注意:如果为true,则在重定向链中会保留初始请求中设置的引用标头。

  • encoding-encoding用于对响应数据进行setEncoding。如果为nullbody则作为Buffer返回。其他任何值(包括的默认值undefined)都将作为编码参数传递给toString()(这意味着默认情况下这实际上是utf8)。(注意:如果希望使用二进制数据,应该设置encoding: null。)
  • gzip-如果为true,则添加Accept-Encoding头以从服务器请求压缩的内容编码(如果尚不存在),并在响应中解码支持的内容编码。注意:响应内容的自动解码在返回的主体数据上执行request(通过request流并传递到回调函数),但不response对流(可从response事件获得)执行,该流是未修改的http.IncomingMessage对象,可能包含压缩的数据。请参见下面的示例。
  • jar-如果为true,请记住cookie以备将来使用(或定义您的自定义cookie jar;请参阅示例部分)

  • agent- http(s).Agent要使用的实例
  • agentClass -或者指定代理商的班级名称
  • agentOptions-并通过其选项。注意:有关HTTPS的信息,请参阅tls API文档中的TLS / SSL选项和上述文档。
  • forever-设置为true使用永久代理 注意:默认为http(s).Agent({keepAlive:true})节点0.12+
  • pool-描述用于请求的代理的对象。如果忽略此选项,则请求将使用全局代理(只要您的选项允许)。否则,请求将在池中搜索您的自定义代理。如果找不到自定义代理,则将创建一个新代理并将其添加到池中。注意: pool仅在agent未指定选项时使用。
    • maxSockets还可以在pool对象上提供一个属性,以设置所有已创建代理的最大套接字数(例如:)pool: {maxSockets: Infinity}
    • 请注意,如果您要循环发送多个请求并创建多个新pool对象,maxSockets则将无法正常工作。要解决此问题,请request.defaults 与您的池选项一起使用,或者使用maxSockets 循环外的属性创建池对象。
  • timeout -包含毫秒数的整数,控制两个超时。
    • 读取超时:在中止请求之前等待服务器发送响应头(并启动响应正文)的时间。
    • 连接超时:将套接字设置timeout为在闲置毫秒后超时。请注意,将超时时间增加到整个OS范围内的TCP连接超时不会有任何效果(Linux中的默认值可以在20-120秒之间)。

  • localAddress -用于绑定网络连接的本地接口。
  • proxy-要使用的HTTP代理。通过基本url身份验证支持代理身份验证,与对参数的支持相同(通过将身份验证信息嵌入uri
  • strictSSL-如果true,要求SSL证书有效。注意:要使用自己的证书颁发机构,需要指定使用该CA作为选项创建的代理。
  • tunnel-控制HTTP CONNECT隧道的行为, 如下所示:
    • undefined(默认)- true如果目的地为httpsfalse否则为
    • true-始终通过CONNECT向代理发出请求来隧道到达目的地
    • false-请求目的地作为GET请求。
  • proxyHeaderWhiteList -发送到隧道代理的标头白名单。
  • proxyHeaderExclusiveList -标头白名单,专门发送给隧道代理而不发送给目的地。

  • time-如果为true,则请求-响应周期(包括所有重定向)的时间以毫秒为单位。设置后,会将以下属性添加到响应对象:
    • elapsedTime整个请求/响应的持续时间(以毫秒为单位)(已弃用)。
    • responseStartTime响应开始的时间戳(以Unix纪元毫秒为单位)(不推荐使用)。
    • timingStart 请求开始的时间戳(以Unix纪元毫秒为单位)。
    • timings包含相对于的毫秒级事件时间戳timingStart。如果存在重定向,则属性反映重定向链中最终请求的时间:
      • socket触发http模块socket事件时的相对时间戳。当套接字分配给请求时,会发生这种情况。
      • lookup触发net模块lookup事件时的相对时间戳。DNS解析后,就会发生这种情况。
      • connectnet模块connect事件触发时的相对时间戳。当服务器确认TCP连接时,就会发生这种情况。
      • responsehttp模块response事件触发时的相对时间戳。从服务器接收到第一个字节时,会发生这种情况。
      • end:收到响应的最后一个字节时的相对时间戳。
    • timingPhases包含每个请求阶段的持续时间。如果存在重定向,则属性反映重定向链中最终请求的时间:
      • wait:套接字初始化的持续时间(timings.socket
      • dns:DNS查找的持续时间(timings.lookup- timings.socket
      • tcp:TCP连接的持续时间(timings.connect- timings.socket
      • firstByte:HTTP服务器响应的持续时间(timings.response- timings.connect
      • download:HTTP下载的持续时间(timings.end- timings.response
      • total:整个HTTP往返持续时间(timings.end
  • har-一个HAR 1.2请求对象,将从HAR格式被加工成覆盖选项匹配的值(见HAR 1.2节的详细信息)
  • callback -或者在选项对象中传递请求的回调

callback参数获得3个参数:

  1. 一个error适用(通常从当http.ClientRequest对象)
  2. 一个http.IncomingMessage对象(响应对象)
  3. 第三个是response正文(StringBuffer,如果json提供了选项,则为JSON对象)

便利方法

还有用于不同HTTP方法的速记方法和其他一些便利。

request.defaults(选项)

此方法返回围绕普通请求API 的包装,该包装默认为您传递给它的任何选项。
注意: request.defaults() 修改全局请求API;而是返回一个包装器该包装器已应用了您的默认设置。
注意:您可以调用.defaults()从返回的包装器 request.defaults来添加/覆盖以前默认的默认值。
例如:

//requests using baseRequest() will set the 'x-token' header
const baseRequest = request.defaults({
  headers: {'x-token': 'my-token'}
})

//requests using specialRequest() will include the 'x-token' header set in
//baseRequest and will also include the 'special' header
const specialRequest = baseRequest.defaults({
  headers: {special: 'special value'}
})

request.METHOD()

这些HTTP方法便利功能的作用类似于,request()但已为您设置了默认方法:

  • request.get():默认为method: "GET"
  • request.post():默认为method: "POST"
  • request.put():默认为method: "PUT"
  • request.patch():默认为method: "PATCH"
  • request.del()/ request.delete():默认为method: "DELETE"
  • request.head():默认为method: "HEAD"
  • request.options():默认为method: "OPTIONS"

request.cookie()

创建新cookie的函数。

request.cookie('key1=value1')

request.jar()

创建新的Cookie罐的函数。

request.jar()

response.caseless.get(’header-name’)

使用不区分大小写的匹配返回指定的响应头字段的函数

request('http://www.google.com', function (error, response, body) {
  // print the Content-Type header even if the server returned it as 'content-type' (lowercase)
  console.log('Content-Type is:', response.caseless.get('Content-Type')); 
});

调试

至少有三种方法可以调试以下各项的操作request

  1. 像这样启动节点进程NODE_DEBUG=request node script.jslib,request,otherlib也可以)。
  2. require('request').debug = true随时设置(这与#1相同)。
  3. 使用request-debug模块查看请求和响应头和主体。

超时时间

如果服务器没有及时响应,则对外部服务器的大多数请求都应附加超时。如果没有超时,您的代码可能会在几分钟或更长时间内打开/使用套接字资源。
超时主要有两种类型:连接超时读取超时。如果在客户端尝试建立与远程计算机的连接时发生超时,则发生连接超时(对应于 套接字上的connect()调用)。每当服务器太慢而无法发回一部分响应时,就会发生读取超时。
这两种情况对请求出了什么问题的含义有很大不同,因此区分它们是很有用的。您可以通过检查err.code“ ETIMEDOUT”值来检测超时错误。此外,您可以通过检查err.connect属性是否设置为来检测超时是否是连接超时 true

request.get('http://10.255.255.1', {timeout: 1500}, function(err) {
    console.log(err.code === 'ETIMEDOUT');
    // Set to `true` if the timeout was a connection timeout, `false` or
    // `undefined` otherwise.
    console.log(err.connect === true);
    process.exit(0);
});

例子:

  const request = require('request')
    , rand = Math.floor(Math.random()*100000000).toString()
    ;
  request(
    { method: 'PUT'
    , uri: 'http://mikeal.iriscouch.com/testjs/' + rand
    , multipart:
      [ { 'content-type': 'application/json'
        ,  body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
        }
      , { body: 'I am an attachment' }
      ]
    }
  , function (error, response, body) {
      if(response.statusCode == 201){
        console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)
      } else {
        console.log('error: '+ response.statusCode)
        console.log(body)
      }
    }
  )

为了向后兼容,默认情况下不支持响应压缩。要接受gzip压缩的响应,请将gzip选项设置为true。请注意,在request未修改响应对象的情况下,传递的正文数据将自动解压缩,并且如果服务器发送了压缩的响应,则将包含压缩的数据。

  const request = require('request')
  request(
    { method: 'GET'
    , uri: 'http://www.google.com'
    , gzip: true
    }
  , function (error, response, body) {
      // body is the decompressed response body
      console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity'))
      console.log('the decoded data is: ' + body)
    }
  )
  .on('data', function(data) {
    // decompressed data as it is received
    console.log('decoded chunk: ' + data)
  })
  .on('response', function(response) {
    // unmodified http.IncomingMessage object
    response.on('data', function(data) {
      // compressed data as it is received
      console.log('received ' + data.length + ' bytes of compressed data')
    })
  })

Cookies默认是禁用的(否则,它们将在后续请求中使用)。要启用cookie,请设置jartrue(中的defaultsoptions)。

const request = request.defaults({jar: true})
request('http://www.google.com', function () {
  request('http://images.google.com')
})

要使用自定义Cookie罐(而不是request的全局Cookie罐),请设置jar为的实例request.jar()(位于defaults或中options

const j = request.jar()
const request = request.defaults({jar:j})
request('http://www.google.com', function () {
  request('http://images.google.com')
})

或者

const j = request.jar();
const cookie = request.cookie('key1=value1');
const url = 'http://www.google.com';
j.setCookie(cookie, url);
request({url: url, jar: j}, function () {
  request('http://images.google.com')
})

要使用自定义 Cookie 存储(例如 FileCookieStore 支持保存到JSON文件和从JSON文件还原的Cookie存储 ),请将其作为参数传递给request.jar()

const FileCookieStore = require('tough-cookie-filestore');
// NOTE - currently the 'cookies.json' file must already exist!
const j = request.jar(new FileCookieStore('cookies.json'));
request = request.defaults({ jar : j })
request('http://www.google.com', function() {
  request('http://images.google.com')
})

Cookie 存储必须是一个 tough-cookie 存储,并且必须支持同步操作。 有关详细信息,请参见 CookieStoreAPI 文档
在请求后检查饼干罐:

const j = request.jar()
request({url: 'http://www.google.com', jar: j}, function () {
  const cookie_string = j.getCookieString(url); // "key1=value1; key2=value2; ..."
  const cookies = j.getCookies(url);
  // [{key: 'key1', value: 'value1', domain: "www.google.com", ...}, ...]
})

原始页面:https://github.com/request/request

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84959 人气
更多

推荐作者

lioqio

文章 0 评论 0

Single

文章 0 评论 0

禾厶谷欠

文章 0 评论 0

alipaysp_2zg8elfGgC

文章 0 评论 0

qq_N6d4X7

文章 0 评论 0

放低过去

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文