遇到的问题:
在用nodejs 的时候,
刚开始使用 pipe 做代理 node 代理网页,在请求真实网站,
最初的代码
// req.pipe(request[req.method.toLowerCase()](req.url)).on('response', (response) => {
}
但是遇到一个问,pipe中出现异常直接会导致程序报错最后异常退出,request 连接超时异常报错
也 可能是由于 所以导致 req 报错
解决办法: 添加异常捕捉, 并添加 jar: true
Cookies are disabled by default (else, they would be used in subsequent requests). To enable cookies, set jar
to true
(either in defaults
or options
).
req.pipe(request[req.method.toLowerCase()]({jar: true, url: req.url},function(error,response,body,next){
if(!error && response.statusCode == 200){
}else{
}
}
后来又发现问题,发现request请求被缓存,导致上次一的request session ,下一次的request session能获取到,
这就导致 传输的session和cookie 会出现问题, 因为是网页代理,所以,上个用户访问呢的session还保存在服务器,这就导致
下次 别的用户请求 url 的时候带着上次留着的 session和cookie ,尤其是多用户同时访问就会出现问题。
To use a custom cookie jar (instead of request
’s global cookie jar), set jar
to an instance of request.jar()
(either in defaults
or options
)
解决办法:
const j = request.jar()
//req.sessionStore.sessions = null
// make the request to the real url
req.pipe(request[req.method.toLowerCase()]({jar: j, url: req.url},function(error,response,body,next){
设置 jar
参考 :
https://github.com/request/request#custom-http-headers
Convenience methods
There are also shorthand methods for different HTTP METHODs and some other conveniences.
request.defaults(options)
This method returns a wrapper around the normal request API that defaults to whatever options you pass to it.
Note: request.defaults()
does not modify the global request API; instead, it returns a wrapper that has your default settings applied to it.
Note: You can call .defaults()
on the wrapper that is returned from request.defaults
to add/override defaults that were previously defaulted.
For example:
//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()
These HTTP method convenience functions act just like request()
but with a default method already set for you:
- request.get(): Defaults to
method: "GET"
. - request.post(): Defaults to
method: "POST"
. - request.put(): Defaults to
method: "PUT"
. - request.patch(): Defaults to
method: "PATCH"
. - request.del() / request.delete(): Defaults to
method: "DELETE"
. - request.head(): Defaults to
method: "HEAD"
. - request.options(): Defaults to
method: "OPTIONS"
.
request.cookie()
Function that creates a new cookie.
request.cookie('key1=value1')
request.jar()
Function that creates a new cookie jar.
request.jar()
response.caseless.get('header-name')
Function that returns the specified response header field using a case-insensitive match
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')); });
Debugging
There are at least three ways to debug the operation of request
:
-
Launch the node process like
NODE_DEBUG=request node script.js
(lib,request,otherlib
works too). -
Set
require('request').debug = true
at any time (this does the same thing as #1). -
Use the request-debug module to view request and response headers and bodies.
Timeouts
Most requests to external servers should have a timeout attached, in case the server is not responding in a timely manner. Without a timeout, your code may have a socket open/consume resources for minutes or more.
There are two main types of timeouts: connection timeouts and read timeouts. A connect timeout occurs if the timeout is hit while your client is attempting to establish a connection to a remote machine (corresponding to the connect() call on the socket). A read timeout occurs any time the server is too slow to send back a part of the response.
These two situations have widely different implications for what went wrong with the request, so it's useful to be able to distinguish them. You can detect timeout errors by checking err.code
for an 'ETIMEDOUT' value. Further, you can detect whether the timeout was a connection timeout by checking if the err.connect
property is set to 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); });
Examples:
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) } } )
For backwards-compatibility, response compression is not supported by default. To accept gzip-compressed responses, set the gzip
option to true
. Note that the body data passed through request
is automatically decompressed while the response object is unmodified and will contain compressed data if the server sent a compressed response.
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 are disabled by default (else, they would be used in subsequent requests). To enable cookies, set jar
to true
(either in defaults
or options
).
const request = request.defaults({jar: true}) request('http://www.google.com', function () { request('http://images.google.com') })
To use a custom cookie jar (instead of request
’s global cookie jar), set jar
to an instance of request.jar()
(either in defaults
or options
)
const j = request.jar() const request = request.defaults({jar:j}) request('http://www.google.com', function () { request('http://images.google.com') })
OR
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') })
To use a custom cookie store (such as a FileCookieStore
which supports saving to and restoring from JSON files), pass it as a parameter to 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') })
The cookie store must be a tough-cookie
store and it must support synchronous operations; see the CookieStore
API docs for details.
To inspect your cookie jar after a request:
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", ...}, ...] })