繁体   English   中英

POST主体未填充TFS REST端点的PHP curl请求设置为application / json

[英]POST body not populating with PHP curl request set to application/json for TFS REST Endpoint

我在这里期望与能力的矛盾中挣扎,希望有人可以帮助我,或者至少确认我没有疯。

我正在尝试使用Node.js和PHP作为往返数据的主要处理器,与本地Microsoft TFS REST端点建立双向Slack集成。 我可以使用NTLM身份验证针对本地TFS安装成功执行GET,并将数据解析到Slack。 因此,我知道(1)端点正在运行,并且(2)我能够对其进行身份验证。

但是,为了对TFS REST端点运行查询,您必须发送内容类型为“ application / json”或“ application / json + patch”的请求。 无论我做什么,在PHP中使用curl或在Node.js应用程序中本机使用,都无法将查询发送到请求正文中并发送到端点。 使用另一页进行测试,如果我将内容类型设置为“ multipart / form-data”或其他标准类型,则可以发送正文,但是TFS会拒绝这些请求作为错误的内容类型。

是否有人知道如何发送内容类型为“ application / json”的POST请求, 使用PHP或Node.js包含正文?

这是我一直在使用的确切PHP(它不会发布主体,但是会发布可以由file_get_contents('php:// input')读取的数据):

$ch = curl_init();
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_URL,$baseURL);    
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Transfer-Encoding: chunked',
    'x-metadata: testing',
    'x-testing: This is a value'
));
$result = curl_exec($ch);

这是来自TFS的错误响应:

“您必须在请求的正文中传递查询对象。”

如果我完全更改删除内容类型标头,则发送正文(通过另一个PHP页面确认),但是随后我从TFS收到此错误:

“该请求指示方法类型\\“ POST \\”的内容类型为\\“ application / x-www-form-urlencoded \\”。此方法的有效内容类型为:application / json,application / json -patch + json。”

更新资料

因此,我可以通过使用自定义请求获得将正文传递给http端点的请求,但是当它尝试连接到托管TFS实例的https端点时,所有标头都将被丢弃,这将返回上面的最后一个错误。

标头发送到https:

'request_header' => string 'POST /tfs/{PROJECT}/_apis/wit/wiql?api-version=2.0 HTTP/1.1
Authorization: NTLM {TOKEN}

标头发送到http:

'request_header' => string 'POST /dev/tfs/post.php HTTP/1.1
Host: {HOST}
Accept: */*
Transfer-Encoding: chunked
x-metadata: testing
x-testing: This is a value
Content-Type: application/json
40
' (length=203)

这是更新的PHP:

$ch = curl_init();
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
//    curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_URL,$baseURL);    
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Transfer-Encoding: chunked',
    'x-metadata: testing',
    'x-testing: This is a value'
));
$result = curl_exec($ch);

更新#2

现在,将标头中的“ Content-Type:application / json”更改为“ Accept:application / json”,将正文发布到http端点,但是标头仍从https端点中删除。

更新#3我可以使用Chrome浏览器中的RESTlet向该端点发出成功的请求,因此TFS端点似乎不是问题,但在PHP脚本和curl之间进行了一些传递。

您可以通过添加以下内容来捕获请求和响应头:

curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
curl_setopt($ch, CURLOPT_ENCODING,"");

curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, true);

$data = curl_exec($ch);
if (curl_errno($ch)){
    echo 'Retreive Base Page Error: ' . curl_error($ch);
}
else {
  $info = rawurldecode(var_export(curl_getinfo($ch),true));
  $skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE)); 
  $responseHeader= substr($data,0,$skip);

echo "<pre>$info\n================\n$responseHeader\n===============\n";
echo substr($data,$skip);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM