[英]PHP Async GET request works on one server, but doesn't on the other
請查看底部的修改以獲取更多信息!
我有兩台服務器。 兩者都應該能夠通過GET請求相互調用。 為了發出請求(它比實際發出請求要激發更多的事件),我在使用以下代碼:
function URLCallAsync($url, $params, $type='POST')
{
foreach ($params as $key => &$val) {
if (is_array($val)) $val = implode(',', $val);
$post_params[] = $key.'='.urlencode($val);
}
$post_string = implode('&', $post_params);
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
// Data goes in the path for a GET request
if('GET' == $type) $parts['path'] .= '?'.$post_string;
$out = "$type ".$parts['path']." HTTP/1.1\r\n";
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
$out.= "Content-Length: ".strlen($post_string)."\r\n";
$out.= "Connection: Close\r\n\r\n";
// Data goes in the request body for a POST request
if ('POST' == $type && isset($post_string)) $out.= $post_string;
fwrite($fp, $out);
fclose($fp);
}
我在兩個服務器上都向函數提供了完全相同的數據(但URL)(我復制了調用文件以對其進行測試!),但是它只能在一個方向上工作!
我將對該函數的調用記錄在日志文件中,以便我可以調查是否出了問題。
服務器A->服務器B,完全可以正常工作,服務器A上的日志文件包含正確的URL
服務器B->服務器A,僅在服務器B的日志文件中打印正確的信息,但服務器A從未收到請求。
發生這種情況的原因可能是什么?
編輯:可能是不同類型的服務器嗎? 服務器A是nginx,服務器B是apache。 服務器A的網址中也有一個“〜”符號,也許就是問題所在? get請求的參數是用php的“ urlencode”編碼的,可能會產生問題嗎?
我嘗試了一下,但問題仍然是請求沒有通過服務器A。但是從瀏覽器來看,請求以某種方式完美運行(假設我使用參數輸入了正確的URL)。
edit2:如果我將“ URLCallAsync”與“ file_get_contents”進行交換,則它應該可以正常工作。 但是問題是file_get_contents被阻止了! 因此它只能是函數本身。 但是奇怪的是它在相反的方向上起作用:(
edit3:函數“ URLCallAsync”運行通過沒有錯誤,注意或其他任何東西。 只是其他服務器未收到它。 file_get_contents到底有何不同???
我知道了
經過對Wireshark的大量擺弄之后,我發現file_get_contents甚至比我的異步函數還簡單!
它只是完全省略了Content-Length字段! 它僅提供“ GET ...”和“主機”。 它還使用HTTP / 1.0而不是1.1,但這沒有任何改變。
因此,解決方案是:同時發布Content-Length標頭(由於我使用GET,其值為0)將以某種方式使服務器拒絕該請求。 我不確定是服務器拒絕了請求,還是其他原因,例如防火牆檢測到了“格式錯誤”的請求,但至少問題得以解決。
因此,下次發送請求時,如果不需要,請不要提供Content-Length標頭:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.