使用cURL
下载图像https://cdni.rt.com/deutsch/images/2018.04/article/5ac34e500d0403503d8b4568.jpg
将此图像从浏览器手动保存到本地PC时,系统显示的大小为139,880字节
使用cURL下载时,文件似乎已损坏,不会被视为有效图像
使用cURL下载时,其大小为139,845,低于手动下载时的大小
进一步挖掘问题,发现服务器将响应头中的内容长度返回为
content-length: 139845
此长度与cURL下载的长度相同,因此我怀疑cURL在服务器达到所谓的(可能是错误的)长度后关闭传输
有没有办法让cURL完全下载文件,即使内容长度标题错误
使用过的代码:
//curl ini
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER,0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT,20);
curl_setopt($ch, CURLOPT_REFERER, 'http://www.bing.com/');
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8');
curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // Good leeway for redirections.
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // Many login forms redirect at least once.
curl_setopt($ch, CURLOPT_COOKIEJAR , "cookie.txt");
//curl get
$x='error';
$url='https://cdni.rt.com/deutsch/images/2018.04/article/5ac34e500d0403503d8b4568.jpg';
curl_setopt($ch, CURLOPT_HTTPGET, 1);
curl_setopt($ch, CURLOPT_URL, trim($url));
$exec=curl_exec($ch);
$x=curl_error($ch);
$fp = fopen('test.jpg','x');
fwrite($fp, $exec);
fclose($fp);
答案 0 :(得分:1)
服务器有Accept-Encoding
压缩传输机制的错误实现。
响应始终是gzip压缩的,但除非客户端在请求中有Accept-Encoding: gzip
标头,否则不会告诉客户端它是gzip压缩的。当服务器没有告诉客户端它被gzip压缩时,客户端在保存之前不会对其进行gzip解压缩,从而导致您的下载损坏。告诉curl通过设置CURLOPT_ENCODING
,
curl_setopt($ch,CURLOPT_ENCODING,'gzip');
,然后服务器将告诉curl它是gzip压缩的,curl会在将它解压缩之前为你解压缩。
你应该告诉服务器管理员这个,这是他的网络服务器中的一个严重错误,破坏了下载。
答案 1 :(得分:0)
libcurl有一个名为CURLOPT_IGNORE_CONTENT_LENGTH
的选项,遗憾的是这在php中本身不受支持,但你可以通过使用正确的幻数来欺骗php设置选项(至少在我的系统上)是136),
if(!defined('CURLOPT_IGNORE_CONTENT_LENGTH')){
define('CURLOPT_IGNORE_CONTENT_LENGTH',136);
}
if(!curl_setopt($ch,CURLOPT_IGNORE_CONTENT_LENGTH,1)){
throw new \RuntimeException('failed to set CURLOPT_IGNORE_CONTENT_LENGTH! - '.curl_errno($ch).': '.curl_error($ch));
}
您可以通过编译和运行以下c ++代码找到适合您系统的编号:
#include <iostream>
#include <curl/curl.h>
int main(){
std::cout << CURLOPT_IGNORE_CONTENT_LENGTH << std::endl;
}