Rumah  >  Artikel  >  pembangunan bahagian belakang  >  node.js获取php curl post数据req.body为空的处理

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

巴扎黑
巴扎黑asal
2016-11-10 10:30:222252semak imbas

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[&#39;content-type&#39;]  
  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)));


Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn