PHP curl 无法正确处理图像
我有一个内部代理,可以从我自己的服务器获取数据并显示给客户端。我希望保持代理端代码最少,并且认为只需将从内容服务器获取的数据按原样发送到客户端即可适用于所有媒体类型。它对于 HTML/TEXT 代码运行良好。但是,不适用于图像。我无法理解为什么。
这是代理端代码:
$curl_url="http//myserver.com/someimage.jpg";
//Open connection
$curl_handle = curl_init();
curl_setopt($curl_handle,CURLOPT_COOKIE,session_name()."=".session_id().";");
//Set the url, number of POST vars, POST data
curl_setopt($curl_handle, CURLOPT_URL, $curl_url);
curl_setopt($curl_handle, CURLOPT_POST, count($_POST));
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $_POST);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
/// curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $curl_request_headers);
/// Above is actually uncommented but omitting details for brevity. They are just
/// HTTP headers passed by the client
curl_setopt($curl_handle, CURLOPT_ENCODING, "identity");
//Execute post
$result = curl_exec($curl_handle);
//Close connection
curl_close($curl_handle);
echo $result;
为什么上面不能正确显示图像? (是否不可能使代理像虚拟桥一样 - 它不解释服务器发送的结果,而只是将其传递并仍然使其适用于所有内容/媒体类型?)。有人可以建议最干净的解决方案吗?
注意:
1) 内容服务器通过 php 脚本处理所有文件,并使用正确传递标头 header('Content-Type: image/jpeg');
如果我直接从服务器访问,它工作正常。但是,从代理中,它不起作用(浏览器显示二进制数据)。
2) 我也不太理解 CURLOPT_HEADER 。
如果我使用
curl_setopt($curl_handle, CURLOPT_HEADER, 1);
浏览器会尝试下载 gzip 压缩数据(对于文本和图像)。
如果我使用
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
浏览器会正确显示文本/图像,但不会显示图像数据。
这些是当我通过代理(直接链接)访问浏览器中的图像时 Google Chrome 显示的响应标头。
Response Headers
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:2576
Content-Type:text/html
Date:Mon, 29 Nov 2010 18:03:52 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=15, max=100
Pragma:no-cache
Server:Apache/2.2.14 (Ubuntu)
Vary:Accept-Encoding
X-Powered-By:PHP/5.3.2-1ubuntu4.5
当我直接在内容服务器上访问图像时的响应标头:
Accept-Ranges:bytes
Connection:Keep-Alive
Content-Length:3669
Content-Type:image/jpeg
Date:Mon, 29 Nov 2010 18:07:25 GMT
ETag:"1802b6-e55-49633c9623e40"
Keep-Alive:timeout=15, max=96
Last-Modified:Mon, 29 Nov 2010 16:44:33 GMT
Server:Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.6 with Suhosin-Patch mod_ssl/2.2.11 OpenSSL/0.9.8g
我有一种感觉,这是由于内容类型是通过代理的 GZIP 造成的。有人可以帮助我理解这一点:默认情况下,apache 不是对图像进行 GZIP 压缩吗? (我同意储蓄可能会更少)。如果不是,那么 CURL(代理)是否对数据进行 Gzip 压缩? CURLOPT_ENCODING、“身份”不应该阻止它吗?我该如何修复?
I have an internal proxy that fetches data from my own server and displays to the client. I wanted to keep the proxy side code minimal, and thought that just sending the data got from the content server as-it-is to the client will work for all media types. It is working fine for HTML/TEXT code. However, not for images. I am unable to understand why.
Here is the proxy side code:
$curl_url="http//myserver.com/someimage.jpg";
//Open connection
$curl_handle = curl_init();
curl_setopt($curl_handle,CURLOPT_COOKIE,session_name()."=".session_id().";");
//Set the url, number of POST vars, POST data
curl_setopt($curl_handle, CURLOPT_URL, $curl_url);
curl_setopt($curl_handle, CURLOPT_POST, count($_POST));
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $_POST);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
/// curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $curl_request_headers);
/// Above is actually uncommented but omitting details for brevity. They are just
/// HTTP headers passed by the client
curl_setopt($curl_handle, CURLOPT_ENCODING, "identity");
//Execute post
$result = curl_exec($curl_handle);
//Close connection
curl_close($curl_handle);
echo $result;
Why does above not display images correctly? (Is it not possible to make the proxy like a dummy bridge - that it does not interpret the result sent by the server but just pass it on and still make it work for all content/media types?). Can someone suggest the cleanest solution?
Notes:
1) The content server handles all files through a php script, and is correctly passing the header usingheader('Content-Type: image/jpeg');
It works fine if I access directly from the server. However from the proxy, it does not work (browser displays binary data).
2)
I don't understand CURLOPT_HEADER very well either.
If I use
curl_setopt($curl_handle, CURLOPT_HEADER, 1);
browser tries to download gzipped data (for text as well as images).
If I use
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
browser displays text/images correctly, but not image data.
These are the response headers shown by Google Chrome, when I access the image in the browser via the proxy (direct link).
Response Headers
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:2576
Content-Type:text/html
Date:Mon, 29 Nov 2010 18:03:52 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=15, max=100
Pragma:no-cache
Server:Apache/2.2.14 (Ubuntu)
Vary:Accept-Encoding
X-Powered-By:PHP/5.3.2-1ubuntu4.5
The response headers when I access image directly on the content server:
Accept-Ranges:bytes
Connection:Keep-Alive
Content-Length:3669
Content-Type:image/jpeg
Date:Mon, 29 Nov 2010 18:07:25 GMT
ETag:"1802b6-e55-49633c9623e40"
Keep-Alive:timeout=15, max=96
Last-Modified:Mon, 29 Nov 2010 16:44:33 GMT
Server:Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.6 with Suhosin-Patch mod_ssl/2.2.11 OpenSSL/0.9.8g
I have a feeling this is due to the Content-type being GZIP via the proxy. Can someone please help me understand this: Aren't images GZIPPed by apache by default? (I agree savings might be less). If not, then is CURL (the proxy) Gzipping the data? Shouldn't CURLOPT_ENCODING, "identity" prevent it? How do I fix?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要使用
header
发送正确的标头来告诉浏览器正确的内容类型,否则它会假设它只是纯文本。You need to send the proper headers using
header
to tell the browser the correct content-type, otherwise it assumes it is just plaintext.好吧,您通过 Curl 将图像作为字符串获取,因此当您 echo $result 时,您正在打印图像的数据,而不是渲染
Well, You're getting the image as a string via Curl, so when you echo $result, you're printing the data for the image as opposed to rendering
<img src="..." />