项目里面需要用到使用NodeJs来转发HTTP POST请求,把过程记录一下:

  1. exports.sendEmail = function (req, res) {
  2. res.send(200, req.body.address);
  3. }

之所以能够访问body的address属性,这得益于express.js(connect)的bodyparser中间件。该中间件解析request的body,假如其content type满足某些条件的话,就尝试将其转换成javascript对象。某些条件是指:multipart, urlencoded, json。

好了,接下来看转发端的代码,为了简单起见,我直接将hard-coding的数据进行转发:

 /**
* nodejs向apache发送请求,接收响应后返回到浏览器端
*/
app.get('/nodeReq', function(req,res,next){
var data = {
age: 20,
name: "cici",
like: "shopping"
};
data = require('querystring').stringify(data); //数据以url param格式发送
data = JSON.stringify(data); //数据以json格式发送
console.log(data);
var opt = {
method: "POST",
host: "localhost",
port: 8012,
path: "/php/get_data.php",
headers:{
//"Content-Type": "application/x-www-form-urlencoded", //for url parameter
"Content-Type": "application/json", // for json data
"Content-Length": data.length
}
}; var req = http.request(opt, function(apacheRes){//建立连接 和 响应回调
if(apacheRes.statusCode == 200){
apacheRes.setEncoding('utf8');
var body = "";
apacheRes.on('data', function(recData){ body += recData;});
apacheRes.on('end', function(){ res.send(body); /*发送收到的响应*/ });
}else{
res.send(500, "error");
}
});
req.write(data + "\n"); //发送请求
req.end(); //请求发送完毕
});

注意,我把content type设置成x-www-form-urlencoded,这是bodyparser所支持的了类型之一,而body的格式通过require('querystring').stringify(...)来格式化的,这个会将对象转换成诸如"address=test%40test.com&subject=test"这种格式的字符串。

另一个是用JSON.stringify()来格式化body内容,然后把content-type改为application/json格式,当然,这个也是body parser所支持的格式之一!

另外,有两个地方,我不是很清楚,一个是貌似content-length不是必须的,另一个是req.write(data+"\n")的"\n"也不是必须的,这个有待研究。。。

补充:

bodyparser的代码在”\node_modules\express\node_modules\connect\lib\middleware\bodyParser.js“,它其实什么都没做,只是把解析body的任务派发给了另外3个中间件:./multipart, ./urlencoded, ./json:

    • ./multipart 负责 application/x-www-form-urlencoded 类型。
    • ./urlencoded 负责 multipart/form-data 类型。
    • ./json 负责 application/json 类型。

用http.request发送文件给服务端, 或带参post数据到服务端

var http = require('http');
var fs = require('fs');
var queryString = require('querystring'); var boundaryKey = 'A' + new Date().getTime(); //随便加个前缀A 避免全数字作为分界符 /**
* 带参数发post请求
*/
function doPost(){
var opt = {
host:'localhost', //注意:不用协议部分(http://)
port:'80',
path: '/testonly/doupload.php', //斜杠开头
method:'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'} //设置content-type 头部
}; var body = '';
var req = http.request(opt, function(res){
res.statusCode == 200 && console.log('REQUEST OK..' );
res.setEncoding('utf8');//res为ClientResponse的实例,是readableStream, 设置字符编码 res.on('data', function(chunk){
body += chunk;
}).on('end', function(){
console.log('Got data: ', body);//end事件中 打印全部响应数据
});
}).on('error', function(err){
console.log('error: ', err.message);
}); var data = {name:'sindy', age:22};
var data1 = JSON.stringify(data);
var data2 = queryString.stringify(data); //注意 querystring.stringify 和 JSON.stringify的区别
console.log(data1);
console.log(data2); req.write(data2); //req为ClientRequest的实例,是writableStream,写数据到流中
req.end();//结束请求
} /**
* 发送文件给服务器并带上其他表单字段数据
*/
function doUpload(){
var opt = {
host:'localhost',
port:'80',
path: '/testonly/doupload.php',
method:'POST',
headers: {'Content-Type':'multipart/form-data; boundary='+boundaryKey, 'Connection':'keep-alive'} //注意:上传文件时的 content-type 设置
}; var body = '';
var req = http.request(opt, function(res){
res.statusCode == 200 && console.log('REQUEST OK..' );
res.setEncoding('utf8'); res.on('data', function(chunk){
body += chunk;
}).on('end', function(){
console.log('Got data: ', body);//php 返回 $_FILES 和 $_POST的内容给客户端
});
}).on('error', function(err){
console.log('error: ', err.message);
}); //ClientRequest writableStream 注意:文件字段的分界符
req.write('--'+boundaryKey+'\r\nContent-Disposition:form-data; name="upfile"; filename="test.zip"\r\nContent-Type:application/x-zip-compressed'); // 1M缓冲
var fileStream = fs.createReadStream('test.zip', {bufferSize: 1024 * 1024});
fileStream.pipe(req, {end: false}); fileStream.on('end', function(){
// ::注意::文件字段内容和其他字段之间空2行,字段名和字段值之间空2行
req.write('\r\n\r\n--'+boundaryKey+'\r\n'+'Content-Disposition: form-data; name="submit"\r\n\r\n'+'sendfile');
req.end('\r\n--'+ boundaryKey + '--'); //注意:结束时的分界符 末尾'--'
}); } // doPost(); doUpload();

转: Nodejs 发送HTTP POST请求实例的更多相关文章

  1. Nodejs发送Post请求时出现socket hang up错误的解决办法

    参考nodejs官网发送http post请求的方法,实现了一个模拟post提交的功能.实际使用时报socket hang up错误. 后来发现是请求头设置的问题,发送选项中需要加上headers字段 ...

  2. Nginx做NodeJS应用负载均衡配置实例

    这篇文章主要介绍了Nginx做NodeJS应用负载均衡配置实例,本文直接给出配置实例,需要的朋友可以参考下. 负载均衡可以把用户的请求分摊到多个服务器上进行处理,从而实现了对海量用户的访问支持.负载均 ...

  3. php 中使用cURL发送get/post请求,上传图片,批处理

    cURL是利用url语法规定传输文件和数据的工具.php中有curl拓展,一般用来实现网络抓取,模拟发送get   post请求,文件上传. 在php中建立curl的基本步骤如下: 1 初始化     ...

  4. Vert.x(vertx)发送 HTTP/HTTPS请求

    Vert.x Web服务有两种协议,一种是HTTP,另外一种是使用ssl的HTTPS,请求的方式有五种,分别是get.post.put.delete.head.为了简单,服务端主要实现对HTTP协议的 ...

  5. nodejs之get/post请求的几种方式

    最近一段时间在学习前端向服务器发送数据和请求数据,下面总结了一下向服务器发送请求用get和post的几种不同请求方式: 1.用form表单的方法:(1)get方法 前端代码: <form act ...

  6. 非域环境下搭建自动故障转移镜像无法将 ALTER DATABASE 命令发送到远程服务器实例的解决办法

    非域环境下搭建自动故障转移镜像无法将 ALTER DATABASE 命令发送到远程服务器实例的解决办法 环境:非域环境 因为是自动故障转移,需要加入见证,事务安全模式是,强安全FULL模式 做到最后一 ...

  7. 如果调用ASP.NET Web API不能发送PUT/DELETE请求怎么办?

    理想的RESTful Web API采用面向资源的架构,并使用请求的HTTP方法表示针对目标资源的操作类型.但是理想和现实是有距离的,虽然HTTP协议提供了一系列原生的HTTP方法,但是在具体的网络环 ...

  8. 调用webapi 错误:使用 HTTP 谓词 POST 向虚拟目录发送了一个请求,而默认文档是不支持 GET 或 HEAD 以外的 HTTP 谓词的静态文件。的解决方案

    第一次调用webapi出错如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http:// ...

  9. nodejs,node原生服务器搭建实例

    nodejs,node原生服务器搭建实例

随机推荐

  1. 安装jdk和tomcat

    安装jdk和tomcat 1,准备工作 虚拟机 VMware :liunx系统镜像 bebian :连接操作软件 putty: 开源图像FTP客户端winspc: Java 语言的软件开发工具包 JD ...

  2. Opencv 完美配置攻略 2014 (Win8.1 + Opencv 2.4.8 + VS 2013)上

    下载安装软件 下载 Opencv for Windows 最新版本,本文是 Opencv 2.4.8.双击后会出现解压提示,实际上就是“安装”了,路径填写为 D:/Program Files,然后确定 ...

  3. [分 享] PHPCMS V9 更换域名,附件地址无法批更新(更换变便)问题>解决方法!!

    大家应该都有在域名更换(比如说,从本地上传到空间)的情况下,用内容>附件管理>附件地址替换 功能. 基本上替换不了所有表中原来域名的地址. 现PHPCMS V9最新版本的依旧存在些问题. ...

  4. python初学笔记(三)

    Unicode字符串 字符串还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节 (byte),所以,一 ...

  5. java后台开发- NOTE

    2015-1-6: IDEA servlet-api.jar idea从14升级到15后,发现 import javax.servlet.AsyncContext; 找不到,右击工程,open mod ...

  6. ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'

    这个错误是说,由于某个SQL操作造成了,表中主键重复. 例子: create table t(x int,y int,z int, primary key(x,y)); insert into t(x ...

  7. ARM Cortex-M3内核的巨大优势

    ARM Cortex-M3相比于ARM其他系列微控制器,具有以下优势或特点: 1. 三级流水线+分支预测 ARM Cortex-M3与ARM7内核一样,采用适合于微控制器应用的三级流水线,但增加了分支 ...

  8. MFC DLL资源动态切换

    在MFC使用过程中,遇到DLL资源与主EXE资源冲突问题. 出现这样的Bug,一时无从下手. 报错位置在核心代码中dlgcore.cpp. [cpp] view plaincopy BOOL AFXA ...

  9. uvalive5818 uva12376 As Long as I Learn, I Live

    题意:给出一个又向图每个图有权值和编号(正方形里的是编号),从第0号节点开始每次向当前节点所连的点中权值最大的节点移动(不会存在权值相同的节点),问最后所在的节点编号和经过的节点的权值之和. 解:模拟 ...

  10. js获取手机重力感应api

    <html> <head> <title>DeviceOrientationEvent</title> <meta charset="U ...