POST正文没有填充PHP curl请求设置为应用程序/ json for TFS REST端点
我正在努力解决期望与功能之间的矛盾,希望有人能帮助我,或者至少证实我'我不疯了。POST正文没有填充PHP curl请求设置为应用程序/ json for TFS REST端点
我正尝试在本地Microsoft TFS REST端点上使用Node.js和PHP作为数据的主要处理器来构建双向Slack集成。我可以使用NTLM身份验证对本地TFS安装成功执行GET,并将数据解析为Slack。所以我知道(1)端点正在工作,并且(2)我能够对其进行身份验证。
但是,为了运行针对TFS REST端点的查询,您必须发送内容类型为“application/json”或“application/json + patch”的请求。无论我做什么,在PHP中使用curl或在Node.js应用程序中使用本地方法,我都无法将请求正文中的查询发送到端点。使用另一个页面来测试这一点,如果我将内容类型设置为“multipart/form-data”或其他标准类型,我可以发送主体,但TFS会拒绝这些请求,因为它们的内容类型错误。
有没有人有任何想法如何发送内容类型的“应用程序/ json”和将包括正文使用PHP或Node.js的POST请求?
下面是我一直使用的确切PHP(不发布机构,但确实可以通过使用PHP的file_get_contents(读取数据后“的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_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:
“的请求指示的内容类型“application/x-www-form-urlencoded”为不支持的方法类型“POST”,此方法的有效内容类型为:application/json,application/json-patch + json。“
更新
这样我就可以得到一个请求,通过使用自定义请求主体传递给HTTP端点,但是当它试图连接到HTTPS端点托管TFS例如,所有的标题是下降,这将返回上面的最后一个错误。发送到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这个端点成功的请求,所以它不会出现在PHP脚本和卷曲之间的传输与TFS端点的问题,而是事提出请求。
您可以通过添加以下捕获请求和响应头:
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);
尝试删除 '''curl_setopt($ CH,CURLOPT_POST,TRUE);''' 并添加 ' ''curl_setopt($ ch,CURLOPT_CUSTOMREQUEST,“POST”); curl_setopt($ ch,CURLOPT_POSTFIELDS,json_encode($ postBody));''' –
刚刚尝试过,并由于某种原因连接到TFS端点(https)导致头完全放弃,而它似乎在工作标准http连接(到另一台服务器)。 'request_header'=>字符串 'POST /tfs/[project]/_apis/wit/wiql?api-version=2.0 HTTP/1.1 授权:NTLM [令牌] HTTP标题: 'request_header'=>字符串' POST /dev/tfs/post.php HTTP/1.1 主机:www.holyelvis.com 接受:*/* 传输编码:分块 的X的元数据:测试 的x测试:这是一个值 内容 - 类型:application/x-www-form-urlencoded '(length = 203) – ctgilley
请确保将内容类型头中的分号更改为冒号。 这是我测试过的一个要点在本地生成一个有效的json请求。也许你可以从那里工作? https://gist.github.com/raddeus/a02c7fcb8ecec37c90f515dacc5fc506 –