有一个静态网页,包含一个表单,表单中有一个文件域,nodejs这边是一个简单的http服务器,在静态网页那边提交了一个文件,在nodejs这边用request.on("data",function(chunk){})获取请求正文的长度,代码如下
var _post_data = "";
request.on("data", function (chunk) {
_post_data += chunk;
console.log("_post_data长度:" + _post_data.length);
})
当整个获取结束之后,查看_post_data的长度与请求头中的content-length长度不符合,要少一点。。。请问这是为啥,我如何才能完整的获取到请求正文,因为想把这个请求正文,原样转发给另外一个地址(用http.request做)
看官方文档,chunk是经过解码后的字符串了,不知道是不是这个原因。。。那如何获得解码前得字符串呢,或者说不让请求正文解码,直接获取到。谢谢各位啦
改了之后,好像大小还是不对。。。请求正文的长度又比Content-Length要长了好多,囧。。。。你知道如何把request获取到的请求体直接当做另外一个request的请求体发出去么,相当于copy了一份,如果用data监听器获取的话,是经过转码的,因为里面有文件的上传,所以请求正文会有二进制数据,不知道经过转码之后是不是就不对了。。。
嗯,搞定啦~直接获取请求主体,然后再次请求,不过现在有一个非常郁闷的问题,就是用http.request请求一个地址,方法是get,其实就是一个302的Redirect,但是请求返回的结果依然是另外一个Redirect 我又把地址直接复制到浏览器里面,是可以正常返回的,状态码是200,用xmlhttprequest也是返回成功,不知道为什么http.request就不对,按道理来说不应该呀
@hot88zh 浏览器处理302一般会重新建立一个TCP连接,请求就不通过你这个代理了。 解析一下302的情况,再发个请求出去也很简单啊。转向地址Location也在header里。 不知道我理解的对不对。
@saighost 好像稍微有点出入,现在是这么一个情况,A→B→C A、B、C是三个不同的网址,其中A到B和B到C,都是程序通过location来跳转,这时候,访问C地址,应该返回200,不应该再返回302了,但是用程序的话,在访问C地址,依然返回302。。。。 我要是把C地址粘贴到浏览器里面,就直接返回200了
用下面这段代码访问上面的地址,返回302,但是在浏览器里面直接访问上面的地址,看控制台应该直接输出200.。。。
http.get({
host:"www.google.com.hk", port:80, path:"/search?tbs=sbi:AMhZZivK0ZITunLa61jpSnTUgxTzXokI3SvM61VJdh8_1jtioUzo-LZMimgb-a3eh0eu6CtIrSOMldhyYsbBsK3H_1PaFE1c6LA4FeeeqH3ZLSO6ocA9tUmVU-XD2IsWQL91FcogEj85LxW_1D9JD62lt6jYMRYyXJAFgws_1BIuWBztJ27pNSGd-2YHGKVPQCOMubdQ9Cs86bYBsKaA1FsyM7MQDqr4WZ9sNeH_1ZLUcbDUTuWTQ25khYsCYmpX2XYDeMGtj_1xwZtlrrMDRINTYDKlCfAKy9CgqYClVWZk9xJSRNDcsyfbUk9rJIY2whiJ70B4e3J0ohq3H5wDeMPRXmM1Lh3AmMZ1sNDXuUs_1Nyey0pqYe41V-aDZzVRObYkvyakU6lUFLegybs4sQxKE8nx8OkzqqOCGqZKQGzysmkWY0XNpfMOMFGPGs-pZqU8P1kFxM1dWJSA-fpNhbxaacdZadbsb98imQVRKI-WGPlEO8y2uaFBbSvF_1L0yQciRzJpXhABB7YN8elIAnSpJRx2Xx3HKzFYqRV4bFXe-8h1ppqUblRlrjCLuH2WNPMOroFb6XEkiE0CbHFIvGnucO4nq4T3vkYUrNWC034ziV5IDfacaGqU6b4ejqSBe_1-2gz-GOdaUrtygNzYtWYlVpWl0XUXcvJuuP3hUHqs1Aqs99I5WUBclqi82YHQRytlIQo_1G16YbDiw1Z9rkJliiPX3iofsMWcWbLsXrK2FBFK4vRj1Wh_1bRlYdCO9P0Hvn6MBCtkcuQCfPKe5HcSvowpofKFlA-Dvm3E7NYVIgPpTmYeH43DyAa9-plERGVchoC_1U1IEPaBIa5qQyqKBez0232oT1A3Ijuh0FjrYYm336YwspyITrdFgFtfDrqe7jUHBC3VbdXZR1pwYm-5A3APIfbNskqiNXJ2x2F57GjFncUiTwqECyZomj4bxFPT0IbGFmzVv97LbTTdIEItAQ2ABHRNGsFG9hKy38iuSUq3DMk5_1ONm7MC4dmEypy9lun1KQ5rf18Z0RyCjs3P76StUl5MnzHBZKUJ_1gWg18c5djMvxWWURwcObDrmgaC7Mssb0CN0CRxLtW0LAzJzxpC9V4-AX3Nc_11xMt45Ui6Mmb2N0k4oIOqGYKSMcTjUK-RoiIgPw00OgNc6qBr-i6h74ArH7iD5LLSq_1f8C0aDN7Y0M0pkEnkbFtF81u7VRQs9agF8LWNv6MnlvHQEzMXNjMtcC1eTTcGiTpiUnuVtXb1hsSFnCjoO9G4D5gHfn7smJaz50Qxq3CrdQLKfpWZ8Y-BukuvbVdVR2_1vg1_1kAlU3-5owOds16WQlTsHHmIb09B8E7PwIqgJfv1y8RtiLR3zhGPxRd4TEc32pHBzdRw" },function(res){ console.log(res.statusCode); });
@leizongmin 嗯,我试试吧。这个地址获取的途径其实是用get请求地址A,获取到的302跳转,而地址A是通过另外一个地址302跳转到。。。嵌套的302跳转,所以我感觉直接用默认的headers可能就行,这个就没加。
@leizongmin 郁闷。。。。我照着浏览器里面把header都加上了,请求完了依然是302跳转,崩溃鸟,用普通的xmlrequesthttp请求都没问题,能正常返回结果。。。你试试呢,就写一个普通的http.request
看看一下代码:第一次请求返回302,然后按照给出的url再请求就200了,参考一下吧
var http = require('http');
var url = require('url');
http.get({
host:"www.google.com.hk",
port:80,
path:"/search?tbs=sbi:AMhZZivK0ZITunLa61jpSnTUgxTzXokI3SvM61VJdh8_1jtioUzo-LZMimgb-a3eh0eu6CtIrSOMldhyYsbBsK3H_1PaFE1c6LA4FeeeqH3ZLSO6ocA9tUmVU-XD2IsWQL91FcogEj85LxW_1D9JD62lt6jYMRYyXJAFgws_1BIuWBztJ27pNSGd-2YHGKVPQCOMubdQ9Cs86bYBsKaA1FsyM7MQDqr4WZ9sNeH_1ZLUcbDUTuWTQ25khYsCYmpX2XYDeMGtj_1xwZtlrrMDRINTYDKlCfAKy9CgqYClVWZk9xJSRNDcsyfbUk9rJIY2whiJ70B4e3J0ohq3H5wDeMPRXmM1Lh3AmMZ1sNDXuUs_1Nyey0pqYe41V-aDZzVRObYkvyakU6lUFLegybs4sQxKE8nx8OkzqqOCGqZKQGzysmkWY0XNpfMOMFGPGs-pZqU8P1kFxM1dWJSA-fpNhbxaacdZadbsb98imQVRKI-WGPlEO8y2uaFBbSvF_1L0yQciRzJpXhABB7YN8elIAnSpJRx2Xx3HKzFYqRV4bFXe-8h1ppqUblRlrjCLuH2WNPMOroFb6XEkiE0CbHFIvGnucO4nq4T3vkYUrNWC034ziV5IDfacaGqU6b4ejqSBe_1-2gz-GOdaUrtygNzYtWYlVpWl0XUXcvJuuP3hUHqs1Aqs99I5WUBclqi82YHQRytlIQo_1G16YbDiw1Z9rkJliiPX3iofsMWcWbLsXrK2FBFK4vRj1Wh_1bRlYdCO9P0Hvn6MBCtkcuQCfPKe5HcSvowpofKFlA-Dvm3E7NYVIgPpTmYeH43DyAa9-plERGVchoC_1U1IEPaBIa5qQyqKBez0232oT1A3Ijuh0FjrYYm336YwspyITrdFgFtfDrqe7jUHBC3VbdXZR1pwYm-5A3APIfbNskqiNXJ2x2F57GjFncUiTwqECyZomj4bxFPT0IbGFmzVv97LbTTdIEItAQ2ABHRNGsFG9hKy38iuSUq3DMk5_1ONm7MC4dmEypy9lun1KQ5rf18Z0RyCjs3P76StUl5MnzHBZKUJ_1gWg18c5djMvxWWURwcObDrmgaC7Mssb0CN0CRxLtW0LAzJzxpC9V4-AX3Nc_11xMt45Ui6Mmb2N0k4oIOqGYKSMcTjUK-RoiIgPw00OgNc6qBr-i6h74ArH7iD5LLSq_1f8C0aDN7Y0M0pkEnkbFtF81u7VRQs9agF8LWNv6MnlvHQEzMXNjMtcC1eTTcGiTpiUnuVtXb1hsSFnCjoO9G4D5gHfn7smJaz50Qxq3CrdQLKfpWZ8Y-BukuvbVdVR2_1vg1_1kAlU3-5owOds16WQlTsHHmIb09B8E7PwIqgJfv1y8RtiLR3zhGPxRd4TEc32pHBzdRw"
}, function (res) {
console.log(res.statusCode);
var direct = url.parse(res.headers.location);
http.get(direct, function (res) {
console.log(res.statusCode);
});
});
另外,服务器端还有返回cookie的,如果你在下次请求时没带上这个信息的话,某些情况下也会导致一直302的。至于为什么浏览器访问就返回200了,那是因为很多工作浏览器都帮你处理了,而你自己用Node.js来模拟这个请求时,需要熟悉http协议的工作原理才行
@leizongmin 嗯,这个确实是200,我当时的代码是让无限这样请求,直到状态码为200,也执行到这步了,但是响应的结果是错误的,跟直接用网页访问这个地址不一样。。下面的代码我也试过了,是正确的
xhr = new XMLHttpRequest();
xhr.open("get", "http://www.google.com.hk/search?tbs=sbi:AMhZZivK0ZITunLa61jpSnTUgxTzXokI3SvM61VJdh8_1jtioUzo-LZMimgb-a3eh0eu6CtIrSOMldhyYsbBsK3H_1PaFE1c6LA4FeeeqH3ZLSO6ocA9tUmVU-XD2IsWQL91FcogEj85LxW_1D9JD62lt6jYMRYyXJAFgws_1BIuWBztJ27pNSGd-2YHGKVPQCOMubdQ9Cs86bYBsKaA1FsyM7MQDqr4WZ9sNeH_1ZLUcbDUTuWTQ25khYsCYmpX2XYDeMGtj_1xwZtlrrMDRINTYDKlCfAKy9CgqYClVWZk9xJSRNDcsyfbUk9rJIY2whiJ70B4e3J0ohq3H5wDeMPRXmM1Lh3AmMZ1sNDXuUs_1Nyey0pqYe41V-aDZzVRObYkvyakU6lUFLegybs4sQxKE8nx8OkzqqOCGqZKQGzysmkWY0XNpfMOMFGPGs-pZqU8P1kFxM1dWJSA-fpNhbxaacdZadbsb98imQVRKI-WGPlEO8y2uaFBbSvF_1L0yQciRzJpXhABB7YN8elIAnSpJRx2Xx3HKzFYqRV4bFXe-8h1ppqUblRlrjCLuH2WNPMOroFb6XEkiE0CbHFIvGnucO4nq4T3vkYUrNWC034ziV5IDfacaGqU6b4ejqSBe_1-2gz-GOdaUrtygNzYtWYlVpWl0XUXcvJuuP3hUHqs1Aqs99I5WUBclqi82YHQRytlIQo_1G16YbDiw1Z9rkJliiPX3iofsMWcWbLsXrK2FBFK4vRj1Wh_1bRlYdCO9P0Hvn6MBCtkcuQCfPKe5HcSvowpofKFlA-Dvm3E7NYVIgPpTmYeH43DyAa9-plERGVchoC_1U1IEPaBIa5qQyqKBez0232oT1A3Ijuh0FjrYYm336YwspyITrdFgFtfDrqe7jUHBC3VbdXZR1pwYm-5A3APIfbNskqiNXJ2x2F57GjFncUiTwqECyZomj4bxFPT0IbGFmzVv97LbTTdIEItAQ2ABHRNGsFG9hKy38iuSUq3DMk5_1ONm7MC4dmEypy9lun1KQ5rf18Z0RyCjs3P76StUl5MnzHBZKUJ_1gWg18c5djMvxWWURwcObDrmgaC7Mssb0CN0CRxLtW0LAzJzxpC9V4-AX3Nc_11xMt45Ui6Mmb2N0k4oIOqGYKSMcTjUK-RoiIgPw00OgNc6qBr-i6h74ArH7iD5LLSq_1f8C0aDN7Y0M0pkEnkbFtF81u7VRQs9agF8LWNv6MnlvHQEzMXNjMtcC1eTTcGiTpiUnuVtXb1hsSFnCjoO9G4D5gHfn7smJaz50Qxq3CrdQLKfpWZ8Y-BukuvbVdVR2_1vg1_1kAlU3-5owOds16WQlTsHHmIb09B8E7PwIqgJfv1y8RtiLR3zhGPxRd4TEc32pHBzdRw", true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log("success!");
}
else if (xhr.status == 302) {
console.log("fuck!");
}
}
else {
console.log(xhr.readyState);
}
}
xhr.send(null);
@leizongmin 找到问题了,。。。原来是google的robot.txt里面做了限制,只能通过浏览器访问,这种问题该肿么办?http.request可以做到模仿浏览器访问么?http://www.google.com/robots.txt
@hot88zh 如果是换baidu没问题,应该检查一下自己代码了,再看看header怎么处理的,是不是有什么隐藏的错误。因为直接http.request没有问题,所以跟XMLHttpRequest或或浏览器访问没关系。