我这里有情况。目前,我开发了一个网站,需要创建一个与设备API进行通信的功能。现在,我受困于 307(临时重定向)。
因此,流程是,首先我需要使用登录功能进行会话。如果登录成功,它将给出响应 307(临时重定向),并且响应头(sessionId)中有Location。因此,要发布另一个请求,我们需要遵循Location(sessionId)。当我在Postman中尝试始终成功执行登录功能以获取Location(SessionId),但是从这些Location发出另一个请求时,有时成功,有时不成功。我试图用PHP制作它,以使登录总是成功并获得Location,但是当POST另一个请求时,它总是失败。
这是用于登录的XML函数:
POST / HTTP/1.1
Host: 111.222.123.123:8001
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:lgi="http://www.qwerty.org/func/LGI">
<soapenv:Header/>
<soapenv:Body>
<lgi:LGI>
<lgi:OPNAME>username</lgi:OPNAME>
<lgi:PWD>password</lgi:PWD>
</lgi:LGI>
</soapenv:Body>
</soapenv:Envelope>
这是登录功能的标题响应:
HTTP/1.1 307 Temporary Redirect
Location: http://111.222.123.123:8001/00112233
Server: Qwerty web server
Content-Type: text/xml; charset="utf-8"
Content-Length: 411
00112233 是发布另一个请求的位置(SessionId)。但是同样,如果来自邮递员,有时会成功,有时不会成功。并且如果从PHP获取位置(SessionId)后始终无法发出POST请求
这是我的登录功能的PHP脚本:
$soapUrl = "http://111.222.123.123:8001/";
$xml_post_string1 = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:lgi="http://www.qwerty.org/func/LGI">
<soapenv:Header/>
<soapenv:Body>
<lgi:LGI>
<lgi:OPNAME>username</lgi:OPNAME>
<lgi:PWD>password</lgi:PWD>
</lgi:LGI>
</soapenv:Body>
</soapenv:Envelope>';
$headers1 = array(
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: http://www.qwerty.org/func/LGI",
"Content-length: ".strlen($xml_post_string1),
);
$url = $soapUrl;
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch1, CURLOPT_URL, $url);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch1, CURLOPT_TIMEOUT, 10);
curl_setopt($ch1, CURLOPT_POST, true);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $xml_post_string1);
curl_setopt($ch1, CURLOPT_HTTPHEADER, $headers1);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_VERBOSE, 1);
curl_setopt($ch1, CURLOPT_HEADER, 1);
$response1 = curl_exec($ch1);
$header_size = curl_getinfo($ch1, CURLINFO_HEADER_SIZE);
$header = substr($response1, 0, $header_size);
$break1= explode('/', $header);
$break2= preg_split('/[\s]+/', $break1[4]);
$sessionId = $break2[0];
这是我获得位置/会话ID后的请求:
$soapUrlToken1 = "http://111.222.123.123:8001/";
$soapUrlToken2 = $soapUrlToken1.$sessionId ;
$xml_post_string2 = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sh="http://www.qwerty.org/func/SH_SUB">
<soapenv:Header/>
<soapenv:Body>
<sh:SH_SUB>
<sh:USER>USERNAME</sh:USER>
<sh:DETAIL>TRUE</sh:DETAIL>
</sh:SH_SUB>
</soapenv:Body>
</soapenv:Envelope>';
$headers2 = array(
"POST /$token HTTP/1.1",
"Host: 111.222.123.123:8001",
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Accept-Encoding: gzip,deflate",
"User-Agent: City Commons-HttpClient/3.1",
"SOAPAction: http://www.qwerty.org/func/SH_SUB",
"Content-length: ".strlen($xml_post_string2),
);
$urlToken = $soapUrlToken2;
//echo "<br />".$urlToken."<br />";
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch2, CURLOPT_URL, $urlToken);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch2, CURLOPT_TIMEOUT, 10);
curl_setopt($ch2, CURLOPT_POST, true);
curl_setopt($ch2, CURLOPT_POSTFIELDS, $xml_post_string2);
curl_setopt($ch2, CURLOPT_HTTPHEADER, $headers2);
$response2 = curl_exec($ch2);
$response3 = str_replace("<SOAP-ENV:Body>","",$response2);
$response4 = str_replace("</SOAP-ENV:Body>","",$response3);
$parser2 = simplexml_load_string($response4);
在php中,关于sessionId的响应始终无效或超时。我已经向API小组询问过,他们仅解释登录后必须维护会话和端口才能发出另一个请求
那么用PHP处理 307(临时重定向)的最佳解决方案是什么?
谢谢
答案 0 :(得分:1)
已经找到了解决方案。获取位置(SessionId)后,我不需要再次使用curl_init()
。 curl_init()
将初始化一个新会话,这是问题所在,之前已经获得的位置(sessionId)将被curl_init()