无法从网络应用程序发出Curl POST请求

时间:2015-03-06 14:16:34

标签: php curl

我正在处理的服务器似乎拒绝出站HTTP请求。我认为这是因为我已经尝试了对API的Guzzlecurl请求。

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()也不会返回任何错误。

3 个答案:

答案 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实例并尝试了它们。他们产生了截然不同的结果:

RequestBin

似乎PHP脚本中的POST数据对发送的内容产生了错误的结果。这可以通过使用内置的PHP函数http_build_query来修复。

它会产生更合适的结果:

RequestBin with fixed problem