我正在处理的服务器似乎拒绝出站HTTP请求。我认为这是因为我已经尝试了对API的Guzzle
和curl
请求。
API与Web服务器位于同一个域中(这在客户端请求时是临时的)。我可以通过Postman
(Chrome插件)向API服务器发出请求,但是当我在服务器上运行相同的请求时,它不会返回任何内容。
以下是“邮差”请求中的标题:
POST /api2/user/session HTTP/1.1
Host: example.com
Connection: keep-alive
Content-Length: 49
Cache-Control: no-cache
Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: PHPSESSID=d9ad79c4c0822fc5c86f4d8799307f1b; _ga=GA1.2.1674422587.1425409444
发布数据:
token=a559d5bba5a9e9517d5c3ed7aeb62db6&user=30972
这很有效。它返回数据。但是当我从我的网络应用程序中调用相同的端点时,我什么都没得到。
$data = urlencode("token=a559d5bba5a9e9517d5c3ed7aeb62db6&user=30972");
$ch = curl_init('http://example.com/api2/user/session');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: ' . strlen($data))
);
$result = curl_exec($ch);
我不明白的是我可以运行以下内容,并返回内容:
print file_get_contents("http://www.google.com");
当我var_dump
端点$_POST
上的user/session
字段时,它会使用Postman
返回postdata数组,但$_POST
字段在通过网络应用。甚至在它向数据库发出任何请求之前,应该设置post字段吗?
通过SSH,这也有效:
curl -F token=a559d5bba5a9e9517d5c3ed7aeb62db6 -F user=30972 http://example.com/api2/user/session
正如我在评论中所建议的那样:
var_dump(function_exists('curl_version'));
// bool(true)
我无法弄清楚发生了什么。
编辑:此作品 ...但我不想使用套接字。必须是卷曲问题。
$fp = fsockopen('example.com', 80);
$vars = array(
'token' => 'a559d5bba5a9e9517d5c3ed7aeb62db6',
'user' => '30972'
);
$content = http_build_query($vars);
fwrite($fp, "POST /api2/user/session HTTP/1.1\r\n");
fwrite($fp, "Host: example.com\r\n");
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-Length: ".strlen($content)."\r\n");
fwrite($fp, "Connection: close\r\n");
fwrite($fp, "\r\n");
fwrite($fp, $content);
header('Content-type: text/plain');
while (!feof($fp)) {
echo fgets($fp, 1024);
}
修改:
curl_error()
也不会返回任何错误。
答案 0 :(得分:1)
事实证明我需要使用http_build_query
。
$vars = array(
'token' => 'a559d5bba5a9e9517d5c3ed7aeb62db6',
'user' => '30972'
);
$content = http_build_query($vars);
$ch = curl_init('http://example.com/api2/user/session');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: ' . strlen($content))
);
$result = curl_exec($ch);
答案 1 :(得分:1)
这可能是由会话锁导致的......如果使用curl访问同一服务器,则使用相同的会话。在脚本运行时,默认情况下会话被锁定,这意味着当前请求必须在为同一会话处理另一个请求之前完成。这将解释curl中请求的超时,因为您的第一个请求未完成而另一个请求已完成...
在session_write_close()
之前使用curl_exec
将解锁会话并更正问题。
答案 2 :(得分:1)
为了更好地理解PHP代码和cURL之间的差异,我创建了一个RequestBin实例并尝试了它们。他们产生了截然不同的结果:
似乎PHP脚本中的POST数据对发送的内容产生了错误的结果。这可以通过使用内置的PHP函数http_build_query来修复。
它会产生更合适的结果: