我试图将curl命令翻译成我可以通过PHP运行的命令。
命令是:
curl -F customerid=902 -F username=API1 -F password=somepassword -F reportname=1002 http://somerandomurl.com/api/v1/getreportcsv
但是,当我尝试通过PHP(最终通过C#)运行时,Web服务会返回错误。知道我的代码出错可能是什么问题吗?我认为Web服务必须对头文件/请求非常具体:
$url = "http://somerandomurl.com/api/v1/getreportcsv";
$fields = [
"customerid" => "902",
"username" => "API1",
"password" => "somepassword",
"reportname" => "1002"
];
$fields_string = "";
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');
//open connection
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
//execute post
$result = curl_exec($ch);
print $result;
Wireshark显示以下差异:
以下是有效的:
POST /somefolder/api/v1/getreportcsv HTTP/1.1
Host: somehost
Accept: */*
Content-Length: 65
Content-Type: application/x-www-form-urlencoded
customerid=902&username=API1&password=somepassword&reportname=1002&HTTP/1.1 200 OK
Server: GlassFish Server Open Source Edition 3.1.1
Content-Type: text/html;charset=UTF-8
Content-Length: 6
Date: Thu, 26 Nov 2015 22:51:23 GMT
ERROR
这个有效:
POST /someurl/api/v1/getreportcsv HTTP/1.1
User-Agent: curl/7.33.0
Host: somehost
Accept: */*
Content-Length: 459
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------4b0d14cc31a40c5b
HTTP/1.1 100 Continue
--------------------------4b0d14cc31a40c5b
Content-Disposition: form-data; name="customerid"
902
--------------------------4b0d14cc31a40c5b
Content-Disposition: form-data; name="username"
API1
--------------------------4b0d14cc31a40c5b
Content-Disposition: form-data; name="password"
somepassword
--------------------------4b0d14cc31a40c5b
Content-Disposition: form-data; name="reportname"
1002
--------------------------4b0d14cc31a40c5b--
HTTP/1.1 200 OK
Server: GlassFish Server Open Source Edition 3.1.1
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 26 Nov 2015 23:13:57 GMT
2000
...snip... the results of the api
显然他们是非常不同的要求,但是我不希望某些东西如此具体?
答案 0 :(得分:1)
这个问题似乎对相关服务非常具体。
但是,问题可能出在标题上。根据{{3}}:
-F [...]使用Content-Type导致curl POST数据 根据RFC 2388
,multipart/form-data
但是,根据curl man page,CURLOPT_POST
选项将使用application/x-www-form-urlencoded
发送数据。
根据同一手册,如果CURLOPT_POSTFIELDS
的值是数组,则Content-Type标头将设置为multipart/form-data
。您也可以尝试将内容类型明确设置为标题。
尝试设置以下cURL选项:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data'));
如果这不起作用,它可能有助于使用-v
参数分析命令行curl发送的所有标头,并尝试设置它们。也可能是明智地设置内容长度标题。