使用Curl PHP,Content-Disposition:form-data发送文件

时间:2017-09-24 10:44:33

标签: php curl

我正在开发一个将文件上传到网站的应用程序。我能够登录,保存cookie并管理Viewstate和事件验证。 但是当我尝试发送文件时,重新创建我从原始站点获取的确切请求,它不起作用。 我附上了代码, 谢谢

原始请求

Upgrade-Insecure-Requests: 1
-----------------------------150408212410782492311667812031:         undefined
Content-Disposition: form-data;         name="ctl00_Corpo_ToolkitScriptManager1_HiddenField"

-----------------------------150408212410782492311667812031
Content-Disposition: form-data; name="__EVENTTARGET"


-----------------------------150408212410782492311667812031
Content-Disposition: form-data; name="__EVENTARGUMENT"


-----------------------------150408212410782492311667812031
Content-Disposition: form-data; name="__VIEWSTATE"

Some-ViewState
-----------------------------150408212410782492311667812031
Content-Disposition: form-data; name="__EVENTVALIDATION"

Some-EventValidation
-----------------------------150408212410782492311667812031
Content-Disposition: form-data; name="ctl00$Corpo$upfAllo";                                 
filename="test.txt"
Content-Type: text/plain
test                       
-----------------------------150408212410782492311667812031
Content-Disposition: form-data; name="ctl00$Corpo$btnElab"

Elabora
-----------------------------150408212410782492311667812031
Content-Disposition: form-data; name="ctl00$Corpo$txtRisultato"


-----------------------------150408212410782492311667812031
Content-Disposition: form-data; name="ctl00$Corpo$Selection"

1
-----------------------------150408212410782492311667812031--

我的回复

$mime_boundary=md5(time());
$eol = "\r\n";
$postData = 'Upgrade-Insecure-Requests: 1'.$eol;
$postData .= '-----------------------------'.$mime_boundary.':     undefined'.$eol;
$postData .= 'Content-Disposition: form-data;     name="ctl00_Corpo_ToolkitScriptManager1_HiddenField"'.$eol.$eol;
$postData .= '-----------------------------'.$mime_boundary.$eol;
$postData .= 'Content-Disposition: form-data;     name="__VIEWSTATE"'.$eol.$eol;
$postData .= '/'.rawurlencode($viewstate).$eol;
$postData .= '-----------------------------'.$mime_boundary.$eol;
$postData .= 'Content-Disposition: form-data; name="__EVENTVALIDATION"'.$eol.$eol;
$postData .= '/'.rawurlencode($eventval).$eol;
$postData .= '-----------------------------'.$mime_boundary.$eol;
$postData .= 'Content-Disposition: form-data; name="ctl00$Corpo$upfAllo"; filename="provainvio.txt"'.$eol;
$postData .= 'Content-Type: text/plain'.$eol.$eol;
$postData .= 'prova'.$eol;
$postData .= '-----------------------------'.$mime_boundary.$eol;
$postData .= 'Content-Disposition: form-data; name="ctl00$Corpo$btnElab"'.$eol.$eol;
$postData .= 'Elabora'.$eol;
$postData .= '-----------------------------'.$mime_boundary.$eol;
$postData .= 'Content-Disposition: form-data; name="ctl00$Corpo$txtRisultato"'.$eol.$eol;
$postData .= '-----------------------------'.$mime_boundary.$eol;
$postData .= 'Content-Disposition: form-data; name="ctl00$Corpo$Selection"'.$eol.$eol;
$postData .= '1'.$eol;
$postData .= '-----------------------------'.$mime_boundary.$eol;

如果我打印我的请求是正确的,但它不起作用。

1 个答案:

答案 0 :(得分:0)

使用curl,不要自己创建表单数据体。您似乎也将某些表单数据正文与http标题混淆了(Upgrade-Insecure-Requests是标题,而Content-Disposition: form-data; name=是请求正文的一部分),并且您错过了1表单数据标题,但无论如何,如果你做得对,curl会为你生成这些,所有这些都应该用这个简单的代码替换,curl将为你处理表单数据协议的细节。

curl_setopt_array ( $ch, array (
        CURLOPT_POST => true,
        CURLOPT_POSTDATA => array (
                'ctl00_Corpo_ToolkitScriptManager1_HiddenField' => '',
                '__EVENTTARGET'=>'',
                '__EVENTARGUMENT'=>'',
                '__VIEWSTATE=>'=>'Some-ViewState',
                '__EVENTVALIDATION'=>'Some-EventValidation',
                'ctl00$Corpo$upfAllo'=>new CURLFile('test.txt','text/plain','test.txt'),
                'ctl00$Corpo$btnElab'=>'Elabora',
                'ctl00$Corpo$txtRisultato'=>'',
                'ctl00$Corpo$Selection'=>'1',
        ) 

) );

另外,你应该检查一下,那些看起来像空字符串,是真的是空字符串,还是看不见的ascii字符?在这种情况下,您需要相应地更新CURLOPT_POSTDATA数组。

还要记得检查curl_setopt_array的返回值,如果设置任何选项时出现问题,则返回bool(false),并且应该使用curl_error来提取错误,并在这种情况下抛出异常。也许像是

function ecurl_setopt_array($ch, array $options) {
    if (! curl_setopt_array ( $ch, $options )) {
        throw new \RuntimeException ( 'curl_setopt_array failed. ' . curl_errno ( $ch ) . ': ' . curl_error ( $ch ) );
    }
}