无法从 Web 应用发出 Curl POST 请求
Can't make Curl POST request from web app
我正在使用的服务器似乎拒绝出站 HTTP 请求。我认为这是因为我已经尝试 Guzzle
和 curl
对 API.
的请求
API 与 Web 服务器位于同一域中(这是根据客户请求临时设置的)。我可以通过 Postman
(Chrome 插件)向 API 服务器发出请求,但是当我 运行 服务器上的相同请求时,它不会 return 随便什么。
这是来自 'Postman' 请求的 headers:
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
Post数据:
token=a559d5bba5a9e9517d5c3ed7aeb62db6&user=30972
这行得通。它 return 是数据。但是当我从我的网络应用程序中调用同一个端点时,我什么也没得到。
$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);
我不明白的是我可以 运行 以下内容,它 return 的内容是:
print file_get_contents("http://www.google.com");
当我 var_dump
端点 user/session
上的 $_POST
字段时,它 return 使用 Postman
的 post 数据数组但是$_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()
也 return 没有错误。
原来我需要用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);
这可能是由会话锁定引起的...如果您使用curl 访问同一台服务器,则使用同一会话。虽然脚本是 运行,但默认情况下会话是锁定的,这意味着当前请求必须在同一会话处理另一个请求之前完成。这可以解释 curl 中的请求超时,因为您的第一个请求未完成,另一个请求...
在 curl_exec
之前使用 session_write_close()
将解锁会话并更正问题。
为了更好地理解 PHP 代码和 cURL 之间的区别,我创建了一个 RequestBin 实例并尝试了这两种方法。他们产生了截然不同的结果:
似乎来自 PHP 脚本的 POST 数据对发送的内容产生了错误的结果。这可以通过使用 built-in PHP 函数 http_build_query.
来解决
它会产生更合适的结果:
我正在使用的服务器似乎拒绝出站 HTTP 请求。我认为这是因为我已经尝试 Guzzle
和 curl
对 API.
API 与 Web 服务器位于同一域中(这是根据客户请求临时设置的)。我可以通过 Postman
(Chrome 插件)向 API 服务器发出请求,但是当我 运行 服务器上的相同请求时,它不会 return 随便什么。
这是来自 'Postman' 请求的 headers:
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
Post数据:
token=a559d5bba5a9e9517d5c3ed7aeb62db6&user=30972
这行得通。它 return 是数据。但是当我从我的网络应用程序中调用同一个端点时,我什么也没得到。
$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);
我不明白的是我可以 运行 以下内容,它 return 的内容是:
print file_get_contents("http://www.google.com");
当我 var_dump
端点 user/session
上的 $_POST
字段时,它 return 使用 Postman
的 post 数据数组但是$_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()
也 return 没有错误。
原来我需要用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);
这可能是由会话锁定引起的...如果您使用curl 访问同一台服务器,则使用同一会话。虽然脚本是 运行,但默认情况下会话是锁定的,这意味着当前请求必须在同一会话处理另一个请求之前完成。这可以解释 curl 中的请求超时,因为您的第一个请求未完成,另一个请求...
在 curl_exec
之前使用 session_write_close()
将解锁会话并更正问题。
为了更好地理解 PHP 代码和 cURL 之间的区别,我创建了一个 RequestBin 实例并尝试了这两种方法。他们产生了截然不同的结果:
似乎来自 PHP 脚本的 POST 数据对发送的内容产生了错误的结果。这可以通过使用 built-in PHP 函数 http_build_query.
来解决它会产生更合适的结果: