需要身份验证时,带有 JSON 中断的跨源 AJAX 请求
Posted
技术标签:
【中文标题】需要身份验证时,带有 JSON 中断的跨源 AJAX 请求【英文标题】:Cross origin AJAX request with JSON breaks when authentication is required 【发布时间】:2015-04-27 23:51:06 【问题描述】:我正在尝试对不同站点上的 php 文件进行 AJAX 调用:
$.ajax(
type: "GET",
dataType: "json",
url: 'http://user:password@www.myurl.com/myphpfile.php',
data:
records: JSON.stringify(workingarray),
account: account,
,
complete: function(response)
var parsedresponse = $.parseJSON(JSON.stringify(response)).responseText.split("<br>");
otherFunction(parsedresponse);
);
我的 PHP 文件:
<?php
header('Access-Control-Allow-Origin: *');
header('content-type: application/json; charset=utf-8');
$records = json_decode($_GET['records']);
$account = $_GET['account'];
.....[LOGIN AND SQL QUERY].....
$result = $conn->query($sql);
while ($row = $result->fetch_assoc())
echo json_encode($row['Some columns']."<br>", JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$conn->close();
?>
这一切都很好,直到我注意到我实际上并没有打开身份验证。一旦我这样做了,整个事情就崩溃了,我总是收到以下错误:
XMLHttpRequest 无法加载 http://user:password@www.myurl.com/myphpfile.php (...) 。不 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://originurl.co.uk” 使用权。响应的 HTTP 状态代码为 401。
正如您将在我的 PHP 代码中看到的那样,存在一个标头。我还尝试将以下 2 行添加到我的 .htaccess 中:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials true
效果令人沮丧,也就是说,没有任何效果。
我已尝试将数据类型转换为 JSONP,但我不确定如何执行此操作...我尝试了以下更改:
$.ajax(
type: "GET",
dataType: "jsonp",
url: 'http://user:password@www.myurl.com/myphpfile.php?callback=?',
data:
records: JSON.stringify(workingarray),
account: account,
,
complete: function(response)
var parsedresponse = $.parseJSON(JSON.stringify(response)).responseText.split("<br>");
otherFunction(parsedresponse);
);
我的 PHP 文件:
<?php
header('Access-Control-Allow-Origin: *');
header('content-type: application/jsonp; charset=utf-8');
...
while ($row = $result->fetch_assoc())
echo $_GET['callback'] . "(" . json_encode($row['Some columns']."<br>", JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . ")";
$conn->close();
?>
据我所知,这不会导致控制台出现错误,但我在响应中唯一能理解的是:
状态:200
statusText:“加载”
(我在complete:
函数中添加了一个console.log(parsedresponse)
行用于调试目的,但我必须承认我并不完全确定如何解释我所看到的大部分内容。)
任何帮助或建议将不胜感激,因为这让我很沮丧。
【问题讨论】:
可能是 OPTION 请求失败,而不是实际的 GET。检查飞行前是否返回 401 或 GET。 感谢您的回复,我很抱歉,但我不确定如何执行您的建议。 当 CORS 发生时,发送 2 个单独的请求,(OPTIONS 和 GET)不仅仅是一个。(只有正常的 GET)。使用嗅探器查看哪个失败并带有 HTTP 401 响应代码。 (你可以使用 Fiddler 或类似的东西来嗅探这个)。 用户名和密码在不加密的情况下从客户端传输到服务器并传入 url 是非常安全的!!! 马文,谢谢你,今天下午我会调查的。 Halayem,我知道基本身份验证在安全方面并不理想,但受密码保护的文件夹中没有特别敏感的信息。尽管如此,我还是更愿意使用更安全的方法。你有什么建议吗?使用 HTTPS 会有帮助吗?虽然如果我这样做,我肯定需要走 JSONP 路线,因为来源不是 HTTPS。我也考虑过取消保护文件夹并将数据库登录信息作为 AJAX 调用的一部分传递,但我不确定这是否更安全...... 【参考方案1】:我相信我已经解决了这个问题 - 我还没有完全重写应用程序,但我能够拨打电话并得到响应,所以从现在开始一切都应该一帆风顺(著名的遗言,哈哈)。
无论如何,我所做的更改如下 - 我首先在 AJAX 调用中将 complete
切换为 success
:
$.ajax(
type: "GET",
dataType: "jsonp",
url: 'https://user:password@www.myurl.com/myphpfile.php?callback=?',
data:
records: JSON.stringify(workingarray),
account: account,
,
success: function(response)
console.log(response);
otherFunction(response);
);
然后,我认为这可能是主要问题,我不得不重写这部分 PHP 文件...
$result = $conn->query($sql);
while ($row = $result->fetch_assoc())
echo json_encode($row['Some columns']."<br>", JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
...变成:
$result = $conn->query($sql);
$rows = array();
while ($row = $result->fetch_assoc())
$rows[] = array('data' => $row['Some columns']);
echo $_GET['callback'] . "(" . json_encode($rows, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . ")";
...显然(回想起来)我以前的方法是返回多个具有相同名称的函数。
我还将请求 URL 更改为 https,我认为这对于预期用途来说应该足够安全。
无论如何希望有人觉得我的经验有用。
【讨论】:
以上是关于需要身份验证时,带有 JSON 中断的跨源 AJAX 请求的主要内容,如果未能解决你的问题,请参考以下文章