我现在不知所措。我试图通过我的 php 应用程序访问Azure Billing & Usage API,但不断收到以下错误:
XMLHttpRequest 无法加载 https://ea.azure.com/rest/{agreementnumber}/usage-reports。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问源“ http://localhost ”。
我知道链接提到的 url 是https://consumption.azure.com/v2/enrollments,但是这对我不起作用,在与 Azure 技术服务联系后,我需要使用旧的 ea.azure.com 入口点。
我正在从我的开发 xampp localhost 服务器以及生产服务器(实时 Intranet 解决方案)中尝试此操作,但无济于事。使用邮递员连接成功,我收到来自 API 的有效响应。
基本上,API 只需要我拥有的 API 密钥。旁边不需要授权。
由于 Postman 成功地从 API 获得了有效响应,我使用了他们的代码生成器来获取我:
- 脚本
- 脚本
- jquery ajax 脚本
他们都为我返回相同的错误;显示了 jquery ajax 之一,因为这是首选:
var settings = {
"async": true,
"crossDomain": true,
"url": "https://ea.azure.com/rest/<?php echo $agreement_number; ?>/usage-reports",
"method": "GET",
"dataType": 'json',
"headers": {
"authorization": "bearer <?php echo $key; ?>"
},
error: function (jqXHR, exception) {
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connected.\n Verify Network.';
} else if (jqXHR.status == 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status == 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
console.log(msg);
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
我不明白为什么 Postman 能够连接到 API 并检索它的信息,而完全相同的代码在我的应用程序中使用时会生成 CORS 错误。
这是否与我的应用程序托管在公司网络内的内部虚拟机中有关,无法从 Internet 访问?
编辑:Rory 提到了 JS 的严格安全限制——因此我也添加了 php 脚本。当我使用 php 5.6 时,默认情况下我没有 httpRequest 类,所以我使用了twslankard 的httpRequest 类并对其进行了调整以接受这样的自定义标头(添加了公共功能):
public function setHeaders($headers) {
if(is_array($headers)) {
foreach($headers as $name => $val) {
$this->headers[$name] = $val;
}
}
}
并像这样调用类:
include_once($_SERVER['DOCUMENT_ROOT'].'/functions/class_httprequest.php');
$request = new HttpRequest($url, 'GET');
$request->setHeaders(array(
'api-version' => '2014-09-02',
'authorization' => $key
));
try {
$response = $request->send();
echo $request->getStatus().'<br>';
echo $request->getResponseBody();
} catch (HttpException $ex) {
echo $ex;
}
使用它确实有效的 php 版本,诀窍是添加 api-version 标头,在此之前我使用 php 脚本返回了一个 http 400 错误。