【发布时间】:2018-01-24 08:03:21
【问题描述】:
我现在很茫然。我试图通过我的 php 应用程序访问Azure Billing & Usage API,但不断收到以下错误:
XMLHttpRequest 无法加载 https://ea.azure.com/rest/{agreementnumber}/usage-reports。回应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此,不允许访问 Origin 'http://localhost'。
我知道链接中提到的 url 是 https://consumption.azure.com/v2/enrollments,但这对我不起作用,在与 Azure 技术服务联系后,我需要使用 older ea.azure.com entry point。
我正在从我的开发 xampp localhost 服务器以及生产服务器(实时 Intranet 解决方案)尝试此操作,但无济于事。使用邮递员连接成功,我收到来自 API 的有效响应。
基本上,API 只需要我拥有的 API 密钥。旁边不需要授权。
由于 Postman 成功从 API 获得有效响应,我使用他们的代码生成器来获取我:
- php 脚本
- javascript 脚本
- 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 class 并对其进行了调整以接受这样的自定义标头(添加了公共功能):
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 错误。
【问题讨论】:
-
I do not understand why Postman is able to connect to the API and retrieve it's information, whilst exactly the same code generates a CORS error when used in my application.这是因为您的代码是 JS,在发出跨域请求时有非常严格的安全限制。邮递员没有。如果您需要这样做并且无法避免 CORS 问题,则需要使用服务器端语言而不是 JS 来发出请求
标签: php jquery azure cors azure-billing-api