【问题标题】:How is a POST request from cURL in PHP like/unlike a POST request from loadVars in Flash?PHP 中 cURL 的 POST 请求与 Flash 中 loadVars 的 POST 请求有何不同?
【发布时间】:2009-08-10 18:27:25
【问题描述】:

全部,

抱歉 - 这可能是一个非常奇怪的问题。

我正在开发 Flash RIA。它所做的其中一件事是调用一个 ASP 页面(位于另一个域中)来检索一些数据。

但是,该 ASP 页面要求用户先登录该站点,然后才能调用该 ASP 页面。

因此,我第一次尝试在 Flash 应用程序中使用它是使用 loadVars.sendAndLoad() 将登录变量发布到登录页面。这会设置 cookie/会话变量来建立我的“登录”状态。然后,稍后,当 Flash 应用程序调用 ASP 页面来请求它需要的数据时,一切正常。换句话说,对第一页的 loadVars.sendAndLoad 调用让我登录,并且保持登录状态(不知何故),因此当 Flash 应用程序稍后调用 ASP 页面时,ASP 页面认为我仍然登录在。

一个很好的解决方案,除了现在 Flash 应用程序将部署在另一个域上。换句话说,ASP 页面(和登录页面)在 domainA.com 上,但 Flash 应用程序将在 domainB.com 上。而且 Flash 应用程序不能调用不同域上的 URL(我知道跨域策略文件,但由于各种原因,这不是一个选项)。

所以,我的下一个想法是——在 domainB.com 上设置一个 PHP 页面,该页面使用 cURL 将登录变量传递给登录页面。在 domainB.com 上设置另一个 PHP 页面,使用 cURL 调用 ASP 页面。

然后,我可以将我的 Flash 应用程序设置为调用那些充当“代理”的 PHP 页面。

但是,这不起作用。当我调用第一个 PHP 页面(将变量传递到 domainA.com 上的登录页面)时,我认为这是可行的。但是,如果我随后调用第二个 PHP 页面,domainA.com 上的 ASP 页面会拒绝该请求,就好像我没有登录一样。

换句话说,当我用 Flash 运行所有内容时 - 似乎从第一个请求到后续请求都保持“登录”状态。但是,当我从 PHP 页面运行所有内容时,不会保持登录状态。

第一个 PHP 页面似乎让我登录了系统。但是第二个 PHP 页面没有被记入登录。

知道在 Flash 和 PHP 中 cookie 的处理方式有何不同,可以解释这种差异吗?

我很乐意根据任何建议或指导提供更多详细信息。

非常感谢!

---- 编辑----

根据非常棒的反馈和建议,我已经完成了这项工作。我还没有机会打磨它;可能某些 cURL 选项是不必要或多余的。但至少,它有效。代码如下:

<?php

    $ckfile = tempnam (".", "CURLCOOKIE");

    $url_1 = 'https://somedomain.com/loginService';
    $url_2 = 'https://somedomain.com/getMyData.asp';

    $fields_1 = array(
        'field1'=>"blah",
        'field2'=>"blah",
        'field3'=>"blah",
    );

    $fields_2 = array(
        'fieldX'=>"blah",
        'fieldY'=>"blah",
        'fieldZ'=>"blah",
    );


    $a='';
    $postvars_1 = '';
    foreach($fields_1 as $key=>$value) { 
        $postvars_1.= $a.urlencode($key).'='.urlencode($value); 
        $a='&'; 
    }

    $a='';
    $postvars_2 = '';
    foreach($fields_2 as $key=>$value) { 
        $postvars_2.= $a.urlencode($key).'='.urlencode($value); 
        $a='&'; 
    }

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
    curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
    curl_setopt($ch, CURLOPT_COOKIE, session_name() . '=' . session_id());
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);    
    curl_setopt($ch, CURLOPT_POST, count($fields));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);

    curl_setopt($ch, CURLOPT_URL, $url_1);
    curl_setopt($ch, CURLOPT_POST, count($fields_1));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars_1);
    $result_1 = curl_exec($ch);

    curl_setopt($ch, CURLOPT_URL, $url_2);
    curl_setopt($ch, CURLOPT_POST, count($fields_2));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars_2);
    $result_2 = curl_exec($ch);

    curl_close($ch);

    header("Content-type: text/xml");
    print $result_2;

    unlink($ckfile);

?>

不用说,可能有更好的方法来实现这一点,或者我的代码存在一些严重问题。但就目前而言,工作总比没有好。如果没有社区和下面的人的帮助,我永远不会让它工作。非常非常感谢!

【问题讨论】:

    标签: php flash curl loadvars


    【解决方案1】:

    你能粘贴问题脚本吗?

    乍一看,我会检查 cookie 是否被捕获并传递给第二个脚本(从 curl 响应中捕获并传递给 curl 以用于第二个请求),curl 不会自动处理 cookie(我不认为) ,你必须扮演网络浏览器的角色,保存响应头(包含cookie)。

    我认为你的脚本应该是这样的:

    <?php
    
        // first request
    
        $url = 'https://somedomain.com/login/';
    
        $fields = array(
            'field1'=>"aaaaa",
            'field2'=>"bbbbb",
            'field3'=>"ccccc"
        );
    
        $postvars = array();
        foreach($fields as $key=>$value) { 
            $postvars[] = urlencode($key).'='.urlencode($value); 
        }
    
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, count($fields));
        curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&',$postvars));
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($ch);
        preg_match('/^Set-Cookie: (.*?);/m', $result, $auth_value);
        curl_close($ch);
    
        // second request
    
        $url = 'https://somedomain.com/getMyData.asp';
        $fields = array(
            'fieldX'=>"xxxx",
            'fieldY'=>"yyyy",
            'fieldZ'=>"zzzz"
        );
    
        $postvars = array();
        foreach($fields as $key=>$value) { 
            $postvars[] = urlencode($key).'='.urlencode($value); 
        }
    
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, count($fields));
        curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&',$postvars));
        curl_setopt($ch, CURLOPT_COOKIE, 'authenticate='.urlencode($auth_value[1]));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($ch);
        curl_close($ch);
    
        print $result;
    
    
    ?>
    

    这是假设您不介意在第一个请求中返回的标题 guff。

    祝你好运

    【讨论】:

    • Dougle - 非常感谢您的回复!如果您有机会再看一遍,我已经添加了脚本。
    【解决方案2】:

    PHP 不会像 flash 那样自动为您处理 cookie。您必须将一组选项传递给执行发布的函数,其中包括用于填充 cookie 的文件路径。

    可以在此处找到有关如何制作该选项包的说明:http://usphp.com/manual/en/http.request.options.php

    【讨论】:

    • 对不起,您必须将路径传递给用于将 cookie 填充到您登录的调用和使用该登录名来执行其他任何操作的调用的文件。
    • Joe - 听起来您已经发现了问题。正如其他人所建议的那样,我已将两个 PHP 脚本合二为一,因此我不需要维护它们之间的登录状态。所以,脚本的前半部分调用了登录页面;第二个页面调用提供数据的 ASP 页面。现在 - 我只需要弄清楚如何跟踪 cookie,并确保两个 cURL 帖子都使用它们。我不知道该怎么做 - 有什么建议吗?非常感谢!
    • 马特,抱歉,我粘贴的链接假设您使用的是 php 的子集,而您显然没有使用。我很高兴你得到了你的答案。
    【解决方案3】:

    登录状态很可能是使用 cookie 维护的。当您通过 PHP 代理时,它不会在请求之间存储 cookie。虽然有一些巴洛克式的方法可以解决这个问题(也许您可以将 cookie 传递回 Flash),但这听起来不像是可扩展或持久的解决方案。是否无法使用跨域策略或其他方式让 Flash 直接联系您正在登录的站点(如 JSON 回调)?

    【讨论】:

    • 内特 - 这是一个很好的观点。我正在考虑将两个PHP脚本合二为一,所以我不需要维护登录状态。所以,脚本的前半部分调用了登录页面;第二个页面调用提供数据的 ASP 页面。即便如此,登录状态也不会被维护。听起来我需要跟踪 cookie,并确保两个 cURL 帖子都使用它们。我不知道该怎么做 - 有什么建议吗?非常感谢!
    • Here 是一个如何在 PHP 的 cURL 模块中使用 cookie 的示例。您既可以存储传入的 cookie,也可以将它们与您的下一个请求一起发送。您需要将 cookie 与您的 Flash 应用程序的会话相关联——通过分别存储每个 Flash 会话的 cookie——以便两个 Flash 会话不会共享一个登录名,这将是一个安全问题。一种方法是将临时 cookie jar 文件名存储在 PHP 的 $_SESSION 变量中。
    • 但是,我还是把这当作最后的手段。任何“非代理”解决方案都将是可取的。
    猜你喜欢
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多