【问题标题】:Stop curl dropping the port number停止 curl 删除端口号
【发布时间】:2011-05-31 17:48:38
【问题描述】:

当我卷曲以下内容时

<?php

$ch = curl_init();
curl_setopt ($ch, CURLOPT_PORT, "8081");
curl_setopt ($ch, CURLOPT_URL, "http://192.168.0.14:8081/comingEpisodes/" );
curl_setopt($ch, CURLOPT_USERPWD, "user:pass");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$curl_response = curl_exec($ch);
curl_close($ch);

echo $curl_response;
?>

返回页面,但不返回图像。我找到了问题所在。 192.168.0.14 是我的本地主机。我正在从应用程序调用一个页面,该页面从端口 8081 运行。Curl 似乎删除了端口并将 192.168.0.14 更改为 locahost,因此图像不再链接到正确的位置。如何确保端口保持不变,以便图像保持不变。谢谢

编辑:我认为移植后的 /comingEpisodes 也是问题的一部分..

【问题讨论】:

  • 什么图片?我不明白你在哪里获取图片
  • 192.168.0.14:8081/comingEpisodes 是一个有图片的网站。页面加载但没有图片,因为 url 已更改为 localhost

标签: php image curl port


【解决方案1】:

除非您正在构建 100% 代理,否则您会将 cURL 拉入的内容转储到浏览器中。结果现在来自 cURL 结果转储到的页面,而不是来自原始 cURL 请求。

基本上,如果您访问 http://localhost 并且上述代码位于 index.php 中,则该页面正在请求 :8081/comingEpisodes 内容并将其转储到原始 @987654322 的 context 中@。浏览器现在基于来自 http://localhost 的所有内容,而不是来自 curl 请求。

可以在文档输出到某个“proxy.php?retrieve=old_url”之前替换文档中的所有内容链接,然后让所有这些现在通过相同的 cURL 上下文进行调用,但这就是网络代理的基础。

End-User               Intermediary              End-Website
(http://localhost)     (localhost/index.php)     (http://192.168.0.14:8081/comingEpisodes/)
------------------     ---------------------     ------------------------------------------
Initial visit--------->
                       cURL Request------------->
                                                 Page Content (html basically)
                       Echoed back to user<------
Content<---------------
Finds <img> etc.------>
                       /comingEpisodes/img1.jpg  // 404 error, it's actually on :8081
                                                 // that localhost has no idea about
                                                 // because it's being hidden using cURL

非常简单的演示

<?php
  //
  // Very Dummied-down proxy
  //

  // Either get the url of the content they need, or use the default "page root"
  // when none is supplied. This is not robust at all, as this really only handles
  // relative urls (e.g. src="images/foo.jpg", something like src="http://foo.com/"
  // would become src="index.php?proxy=http://foo.com/" which makes the below turn
  // into "http://www.google.com/http://foo.com/")
  $_target = 'http://www.google.com/' . (isset($_GET['proxy']) ? $_GET['proxy'] : '');

  // Build the cURL request to get the page contents
  $cURL = curl_init($_target);
  try
  {
    // setup cURL to your liking
    curl_setopt($cURL, CURLOPT_RETURNTRANSFER, 1);

    // execute the request
    $page = curl_exec($cURL);

    // Forward along the content type (so images, files, etc all are understood correctly)
    $contentType = curl_getinfo($cURL, CURLINFO_CONTENT_TYPE);
    header('Content-Type: ' . $contentType);

    // close curl, we're done.
    curl_close($cURL);

    // test against the content type. If it HTML then we need to re-parse
    // the page to add our proxy intercept in the URL so the visitor keeps using
    // our cURL request above for EVEYRTHING it needs from this site.
    if (strstr($contentType,'text/html') !== false)
    {
      //
      // It's html, replace all the references to content using URLs
      //

      // First, load our DOM parser
      $html = new DOMDocument();
      $html->formatOutput = true;
      @$html->loadHTML($page); // was getting parse errors, added @ for demo purposes.

      // simple demo, look for image references and change them
      foreach ($html->getElementsByTagName('img') as $img)
      {
        // take a typical image:
        //   <img src="logo.jpg" />
        // and make it go through the proxy (so it uses cURL again:
        //   <img src="index.php?proxy=logo.jpg" />
        $img->setAttribute('src', sprintf('%s?proxy=%s', $_SERVER['PHP_SELF'], urlencode($img->getAttribute('src'))));
      }

      // finally dump it to client with the urls changed
      echo $html->saveHTML();
    }
    else
    {
      // Not HTML, just dump it.
      echo $page;
    }
  }
  // just in case, probably want to do something with this.
  catch (Exception $ex)
  {
  }

【讨论】:

  • 如果是这种情况,那么当您卷曲页面时说 www.xyz.co.za 如果所有图片更改为相对于本地主机,为什么所有图片都可以工作?
  • @Michael:快速解决方案:在回显之前执行str_replace('&lt;/head&gt;','&lt;base href="http://192.168.0.14:8081/comingEpisodes/" /&gt;&lt;/head&gt;',$curl_response);,这样浏览器就会知道去哪里查找。
  • @Michael:回答最直接的问题,它们可能是绝对地址,而不是相对地址。 &lt;img src="http://..." /&gt;&lt;img src="images/01.jpg" /&gt; 的区别(浏览器将转换为 http://locahost/images/01.jpg 而不是(所需的)http://192.168.0.14:8081/comingEpisodes/images/01.jpg。)
  • @Brad:您所建议的问题是,它会再次调用服务器以获取图像,并且服务器已通过身份验证,因此它会再次弹出请求进行身份验证。我可以以某种方式将身份验证包含在您的建议中吗?
  • @Michael:是的,您必须拦截 每个 内容调用并将您的 cURL 方法应用于它。基本上,初始调用获取页面内容。然后解析任何href="..."src="..." 等的内容并将其重写为(例如)href="index.php?proxy=[original_link]"
猜你喜欢
  • 2014-07-18
  • 2011-07-04
  • 2015-08-17
  • 2013-12-27
  • 2015-10-21
  • 2017-01-01
  • 2016-02-06
相关资源
最近更新 更多