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 interealbus the fgot; tiparty and connect-multiparty
formidable
multer
This module provides the following parsers:
JSON body parser
M
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}"; }
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') })
這行shouldParse 返回false
再到type-is.js/index.js 返回false。var value = req.headers['content-type']
Java代碼
// determine if request should be parsed if (!shouldParse(req)) { return ('skip parsing'), next() }
發現這裡的req.headers['content-type'
發現這裡的req.headers['content-type'] 是m. /x-www-form-urlencoded
原來,在php執行curl的時候,postData是數組,會將資料編碼設定為multipart/form-data
Java CURLOPT_POSTFIELDS,cURL會把資料編碼成 multipart/form-data,而然傳遞一個URL-encoded字串時,資料會被編碼成 application/x-www-form-urlencoded。
修改pHP代碼
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) }