node.js获取php curl post数据req.body为空的处理

巴扎黑
发布: 2016-11-10 10:30:22
原创
2133 人浏览过

node使用了express4和body-parser来解析php curl的数据,但是获取的req.body是{},设置了header 

前提知识: 

body-parser不支持解析multi/form-data的功能,如果是传递二进制数据或者文件上传,就不能用它了。 

Node.js body parsing middleware. 

This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules: 

busboy and connect-busboy 
multiparty and connect-multiparty 
formidable 
multer 
This module provides the following parsers: 

JSON body parser 
Raw body parser 
Text body parser 
URL-encoded form body parser 

参考: 
https://github.com/expressjs/body-parser#bodyparserurlencodedoptions 

PHP 代码 

Java代码  

function addCurl($url, $type="get", $postData=null)  
    {  
        $ch = curl_init();  
        $headers[] = 'Connection: Keep-Alive';  
        $headres[] = 'Content-Type: application/x-www-form-urlencoded;charset=utf-8';         
        $headers[] = 'Content-Length: ' . strlen(json_encode($postData));  
        //$headres[] = 'Content-Type: application/json';  
        //$headres[] = 'Content-Type: text/html';  
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);  
        curl_setopt($ch, CURLOPT_HEADER, 0);  
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  
        if ($type=="get") {  
            curl_setopt($ch, CURLOPT_POST, 0);  
        } else {  
            curl_setopt($ch, CURLOPT_POST, 1);  
            curl_setopt($ch, CURLOPT_POSTFIELDS, urlencode(json_encode($postData)));  
        }  
        curl_setopt($ch, CURLOPT_URL, $url);  
        $data = curl_exec($ch);  
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);  
          
        if (curl_errno($ch)) {  
            echo 'Curl error: ' . curl_error($ch) . PHP_EOL;  
            curl_close($ch);  
            return false;  
        }   
        curl_close($ch);  
        return ($code == 200) ? $data : "server error,code: . {$code}";  
    }
登录后复制

node 代码

Java代码

var express = require('express')  
var bodyParser = require('body-parser')  
  
var app = express()  
var urlencodedParser = bodyParser.urlencoded({ extended: false })  
app.use(urlencodedParser, function (req, res) {  
  res.setHeader('Content-Type', 'text/plain')  
  res.write('you posted:\n')  
  res.end(JSON.stringify(req.body, null, 2))  
})  
  
app.listen(3000, function() {  
    console.log('Server is running')  
})
登录后复制

指定了解析方式依然不行。就到body-parser的源码中一行行调试下去。

找到urlencode.js

Java代码

// determine if request should be parsed  
    if (!shouldParse(req)) {  
      return ('skip parsing'), next()  
    }
登录后复制



这行shouldParse 返回false
再到type-is.js/index.js 返回false。
var value = req.headers['content-type']


Java代码

function typeofrequest(req, types_) {  
  var types = types_  
  // no body  
  if (!hasbody(req)) {  
    return null  
  }  
  
  // support flattened arguments  
  if (arguments.length > 2) {  
    types = new Array(arguments.length - 1)  
    for (var i = 0; i < types.length; i++) {  
      types[i] = arguments[i + 1]  
    }  
  }  
  // request content type  
  var value = req.headers['content-type']  
  return typeis(value, types)  
}
登录后复制



发现这里的req.headers['content-type'] 是 multipart/form-data,而type是application/x-www-form-urlencoded

原来,在php执行curl的时候,postData是数组,会将数据编码设置为 multipart/form-data

Java代码

Note:

传递一个数组到CURLOPT_POSTFIELDS,cURL会把数据编码成 multipart/form-data,而然传递一个URL-encoded字符串时,数据会被编码成 application/x-www-form-urlencoded。



修改pHP代码

Java代码

curl_setopt($ch, CURLOPT_POSTFIELDS, urlencode(json_encode($postData)));
登录后复制


相关标签:
php
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!