PHP中的cURL的POST请求如何/不同于来自Flash中的loadVars的POST请求?

时间:2009-08-10 18:27:25

标签: php flash curl loadvars

所有

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

我正在开发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);

?>

毋庸置疑,可能有更好的方法来实现这一点,或者我的代码存在一些严重问题。但是,现在工作比没有好。没有社区和下面的人的帮助,我从来没有让这个工作。很多,非常感谢!

3 个答案:

答案 0 :(得分:1)

可以粘贴问题脚本吗?

乍一看,我会检查cookie是否被捕获并传递到第二个脚本(从卷曲响应中捕获并传递给第二个请求的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回来。

祝你好运

答案 1 :(得分:1)

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

答案 2 :(得分:1)

PHP不会像闪存一样自动处理cookie。您必须传递给发布帖子的函数,这是一个选项包,包括文件路径以填充cookie。

有关如何制作这个选项的说明,请访问:http://usphp.com/manual/en/http.request.options.php