【问题标题】:When uploading a file with cURL the file gets modified with header information使用 cURL 上传文件时,文件会使用标题信息进行修改
【发布时间】:2020-04-18 09:12:39
【问题描述】:

使用 cURL 上传文件时,我发现远程端的文件正在被修改,并且标头信息被转储到文件中。我怀疑这是我的标题信息中的内容,但除此之外我迷路了。我几乎在尝试任何东西。

这是我正在使用的代码。

$fLocation = realpath('file.csv');  
$finfo = finfo_open(FILEINFO_MIME_TYPE);  
$fType = finfo_file($finfo, $fLocation);  
finfo_close($finfo);      
$cFile = curl_file_create($fLocation);  
$post = array('file'=> $cFile);  
$ch = curl_init();  
curl_setopt($ch, CURLOPT_URL, $url);  
curl_setopt($ch, CURLOPT_POST,1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
curl_setopt($ch, CURLOPT_USERPWD, $username.":".$password);  
curl_setopt($ch, CURLOPT_HTTPHEADER, "Content-Type: application/octet-stream");  
$result = curl_exec($ch);  

我已经为标头尝试了几种不同的 Content-Type,从 application/binary 到 multipart/form-data,甚至根本没有在标头中发送 content-type。我怀疑我需要在标题中添加更多内容。

无论如何,我发送的文件是 .csv,但我想最后发送一个 .xlsx 文件(我正在使用 .csv 进行测试)。当我从远程服务器获取文件并在文本编辑器中打开它时,我看到文件的开头和结尾添加了信息,文件的原始数据介于两者之间。这是添加到顶部的内容。

=--------------------------a0fe4530540c659b  
Content-Disposition: form-data; name="file"; filename="/home/username/website/path/file.csv"  
Content-Type: application/octet-stream 

还有,底部

--------------------------a0fe4530540c659b--

本质上,当我所有的 .xlsx 文件到达另一端时,它们都损坏了,我就明白了这一点。我将发送的内容更改为纯文本文件 (CSV),这时我才意识到发生了什么。

这里有更多有趣的信息。实际上是我通过他们的 API 向 ZenDesk 发送了一些东西,而且我显然是在 PHP 中使用 cURL 执行此操作的。当我收到 Zendesk 的 JSON 回复时,其中一部分看起来像这样......

[file_name] => file.csv  
[content_url] => https://org.zendesk.com/attachments/token/jdjdjdjdjdjhdjdjdj/?name=file.csv  
[content_type] => multipart/form-data  
[size] => 5615  

有趣的是,它看到了我上传的多部分/表单数据。即使我更改标头中的 Content-Type 也是如此。

我肯定在这里错过了一些愚蠢而简单的东西。

【问题讨论】:

  • 大家都知道,这与标题有关。这是最终为我解决问题的代码。
  • 顺便说一句,您实际上是在使用标题。当你给 CURLOPT_POSTFIELDS 一个数组时,curl 将以Multipart/form-data 格式上传文件,其中正确的标题看起来像Content-Type: multipart/form-data; boundary=------------------------fe1569598bc62ae7 - 但是你发送了Content-Type: application/octet-stream,告诉服务器你发送了原始文件(和原始!=多部分/表单数据)

标签: php curl content-type zendesk zendesk-api


【解决方案1】:

您无需设置Content-Type: application/octet-stream 或其他标题即可上传文件。只需使用curl_file_create 方法发送您的文件。

您的代码必须是这样的:

if (function_exists('curl_file_create')) { // for php 5.5+
    $File_Address = curl_file_create($file_name_with_full_path);
} else {
    $File_Address = '@' . realpath($file_name_with_full_path);
}

$post = array('file_name'=> $File_Address);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_USERPWD, $username.":".$password);

$result = curl_exec($ch);

【讨论】:

  • 感谢您的回复,但没有bueno。我不再得到“=-------------------------a0fe4530540c659b”,但我仍然得到 CSV 文件中的内容。我想一定有别的东西
  • @PaulMichael 您现在可以知道上传后文件中的内容吗?我认为您的源文件可能有问题!
  • 我的源文件绝对不是问题。它很干净。在我上传文件之前,它有 30 行信息,2 列。上传后,30 行被下推,前 2 行填充 Content-Disposition: form-data;名称=“文件”; filename="/home/username/website/path/file.csv" Content-Type: application/octet-stream ------ 因此,另一端的文件在流中的某处被破坏。远端正在接受我的整个请求并将其制作为文件。我只需要它接受文件,不包括标题。
【解决方案2】:

大家都知道,这与标题有关。这是最终为我解决问题的代码。

$ch = curl_init();
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10 );
curl_setopt($ch, CURLOPT_URL, $json_url);
curl_setopt($ch, CURLOPT_USERPWD, $username.":".$password);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/binary'));
curl_setopt($ch, CURLOPT_POST, true);
$file = fopen($fLocation, 'r');
$size = filesize($fLocation);
$fildata = fread($file,$size);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fildata);
curl_setopt($ch, CURLOPT_INFILE, $file);
curl_setopt($ch, CURLOPT_INFILESIZE, $size);
curl_setopt($ch, CURLOPT_USERAGENT, "MozillaXYZ/1.0");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$result = curl_exec($ch);

【讨论】:

  • 警告,如果 uploader 在 Windows 上运行,此代码会弄乱二进制数据。要获得适用于 Linux 和 Windows 的安全可移植行为,请将 $file = fopen($fLocation, 'r'); 更改为 $file = fopen($fLocation, 'rb');
猜你喜欢
  • 1970-01-01
  • 2015-05-14
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-12
相关资源
最近更新 更多