Zend_Http_Client - 为什么我的 POST 请求发送了错误的内容类型标头


Zend_Http_Client - Why does my POST request send the wrong content-type header?

我正在使用Zend Http客户端调用外部服务。该服务允许我将文件上传到他们的存储系统。它要求在查询字符串中发送相关的参数(userid 等),并且文件上传内容应该在 POST 正文中以"application/zip"的内容类型发送(我正在发送一个包含各种内容的 zip 文件)。

为此,我使用 zend 客户端的 setParameterGet() 函数在查询字符串中设置参数。然后,我使用 setFileUpload() 函数设置文件上传内容:

$this->client->setFileUpload($zipFilePath, 'content', null, 'application/zip');

但是,该服务告诉我我向其发送了错误的内容类型,即"多部分/表单数据"

以下是 Zend 客户端发送到服务的原始标头(请注意,我已经删除了一些敏感信息,将它们替换为括在 [] 括号中的项目名称)

发布 https://[ServiceURL]?cmd=[COMMAND]&enrollmentid=[ENROLLMENTID]&itemid=[ITEMID]

HTTP/1.1

主机

:[主机] 接受编码:gzip,压缩

用户代理: Zend_Http_Client 饼干:

AZT=9cMFAIBgG-eM1K|Bw7Qxlw7pBuPJwm0PCHryD;

内容类型:多部分/表单数据;边界=---ZENDHTTPCLIENT-05535ba63b5130ab41d9c75859f678d8

内容长度:2967

-----ZENDHTTPCLIENT-05535ba63b5130ab41d9c75859f678d8

内容处置:表单数据; 名称="内容"; 文件名="agilixContent.zip"

内容类型:应用程序/压缩

[原始文件数据在这里]

所以基本上,即使我设置了 POST 内容类型标头,我的外部服务也会告诉我我发送了错误的内容类型,因为还有另一个内容类型标头的值为"多部分/表单数据"。我尝试更改/删除该内容标题,但无济于事。如何删除该标头,以便我的请求中不会出现这两个重复的"内容类型"标头?

如果要使用"application/zip"作为内容类型上传文件,则不应使用->setFileUpload(),而应使用->setRawData()setFileUpload()用于模仿基于HTML表单的文件上传,这不是您所需要的。

有关详细信息,请参阅 http://framework.zend.com/manual/en/zend.http.client.advanced.html#zend.http.client.raw_post_data。您需要的(基于原始示例)将是这样的:

$zipFileData = file_get_contents($zipFilePath);
$this->client->setRawData($zipFileData, 'application/zip');
$response = $this->client->request('POST');

请注意,如果您的 ZIP 文件可能非常大(例如超过几兆字节),您可能需要使用 ZHC 的流媒体支持功能,因此请避免占用内存。如果您知道您的文件总是小于 5-10 兆字节,我不会打扰它。

我不确定如何使用 Zend HTTP 客户端做到这一点,但我相信你可以用普通的 cURL 做到这一点。正如你一定知道cURL给你很大的灵活性,我没有深入研究Zend,但Zend有可能在内部使用cURL。

<?php
// URL on which we have to post data
$url = "http://localhost/tutorials/post.php";
// Any other field you might want to catch
$post_data = "khan";
// File you want to upload/post
//$post_data['zip_file'] = "@c:/foobar.zip";
$headers[] = "Content-Type: application/zip";
// Initialize cURL
$ch = curl_init();
// Set URL on which you want to post the Form and/or data
curl_setopt($ch, CURLOPT_URL, $url);
// Data+Files to be posted
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// Set any custom header you may want to set or override defaults
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
// Pass TRUE or 1 if you want to wait for and catch the response against the request made
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// For Debug mode; shows up any error encountered during the operation
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Execute the request
$response = curl_exec($ch);
// Just for debug: to see response
echo $response;

我希望上面的片段对您有用。这是我下面提到的博客文章中的修改代码。

参考: http://blogs.digitss.com/php/curl-php/posting-or-uploading-files-using-curl-with-php/