【问题标题】:Why does Ajax give me a cross origin error when I can make the request from PHP?当我可以从 PHP 发出请求时,为什么 Ajax 会给我一个跨源错误?
【发布时间】:2014-11-03 23:24:35
【问题描述】:

我可以从 PHP 发出 GET 请求并获得正确的响应。这是我使用的功能:

PHP

function httpGet($url)
{
    $ch = curl_init();

    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch,CURLOPT_HEADER, false);

    $output=curl_exec($ch);
    curl_close($ch);
    return $output;
}

一个简单的例子:

$fakevalue='iamfake';
$url="http://fakeurl.com?fakeparameter=".$fakevalue;
$jsondata= httpGet($url);
$fake_array = json_decode($jsondata, true);
$weed_var=$fake_array['weeds']; // successfully obtained weed.

此函数返回来自服务器的响应。

现在我在 AJAX 中尝试相同的 HTTP GET 请求,但我无法获得响应。

最初我认为问题出在我使用的 JavaScript 函数上。 Google 为我提供了许多 JavaScript 函数来执行 HTTP GET 请求,但它们都有同样的问题。请求返回一个错误,而不是我使用 PHP 时得到的数据。

JAVASCRIPT

var fakevalue = "iamfake";

var fake_data = {
    fakeparameter: fakevalue
};

$.ajax({
    url: "http://fakeurl.com",
    data: fake_data,
    type: "GET",
    crossDomain: true,
    dataType: "json",
    success: function(a) {
        $("#getcentre").html(a);
    },
    error: function() {
        alert("Failed!");
    }
});

JavaScript 出错

XMLHttpRequest cannot load http://fakeurl.com?fakeparameter=fakevalue. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.`

我知道你会告诉我使用 CORS,但如果是因为缺少“Access-Control-Allow-Origin”标头,那么我如何在 PHP 中获得相同服务的响应?

【问题讨论】:

  • 浏览器拒绝了您对与当前域不同的域的请求。当您使用 PHP 时,运行 PHP 代码的服务器充当客户端并执行 GET 请求。当浏览器执行 AJAX 请求时,远程服务器(如果不是同一个域)必须明确允许它 - 服务器将Access-Control-Allow-Origin 发送回来。有区别,是的,CORS 就是答案。
  • Google Chrome、Mozilla Firefox、IE——我在所有这 3 个浏览器中都试过了。错误是一样的。那么这是因为浏览器的原因吗? @NB
  • 昆汀在他的回答中很好地解释了这一点。每个浏览器都必须实现这一点以符合标准,这主要是因为安全。
  • @Hi_Daddy — 因为他们标准化了一个通用的安全模型。这是一项功能,而不是错误。
  • 即使阅读en.wikipedia.org/wiki/Cross-origin_resource_sharing 也应该已经告诉你所有你需要知道的......你要么需要学习如何做一些基础研究,要么首先要了解技术方面的解释。

标签: javascript php jquery ajax get


【解决方案1】:

使用 PHP(或在您的服务器上运行的任何其他应用程序,或独立应用程序(包括作为浏览器扩展安装的应用程序)),正在使用 您的 从 Bob 的服务器请求数据strong> 凭据(您的 cookie、您的 IP 地址、您的所有其他信息)。

使用 Ajax, 要求 Alice 的 浏览器使用 她的 凭据从 Bob 的服务器请求数据,然后将这些数据提供给您的JavaScript(然后可以将其发送回您的服务器,以便您自己查看)。

Bob 可能会给 Alice 不同的数据,然后他会给你。例如:Bob 可能正在运行 Alice 的电子银行系统或公司内部网。

因此,除非 Bob 的服务器告诉 Alice 的浏览器可以向您提供该数据(使用 CORS),否则浏览器将阻止您的 JavaScript 访问该数据。

有 CORS 的替代方案,但它们涉及使用并非设计为数据格式 (JSONP) 的文件类型分发数据(这也需要 Bob 的服务器配合)或让您的服务器从Bob 然后通过您服务器上的 URL 使其可用(或两者的某种组合,如 YQL 所做的)(这意味着您获得的是 Bob 将提供给您的数据,而不是 Bob 将提供给 Alice 的数据)。

【讨论】:

  • SO....有什么方法可以告诉 Alice 给我我正在寻找的数据?我知道鲍勃是罪魁祸首。但是有什么方法可以让 Alice 帮我获取数据???
  • 是的,访问 Bob 的服务器并添加 Access-Control-Allow-Origin -- 就像错误消息告诉你的那样。
  • 如果我将 Access-Control-Allow-Origin 设置为 *,那么每个带有网络浏览器和互联网连接的笨蛋都可以访问服务器或类似的东西......对吗??? @米海斯坦库
  • 就像@MihaiStancu 说的 - 你需要让服务器发送Access-Control-Allow-Origin BACK。这证明服务器将您识别为有效的用户/权限。这意味着您需要检测(在 Bob 的服务器上)该请求来自 Alice 的域,然后您需要明确证明 Bob 的服务器可以接受。此握手以发送Access-Control-Allow-Origin: alice-in-wonderland.com 的形式完成。如果这没有到位,想象一下通过使用从某个地方获得的脚本(间谍软件在这里尖叫)可能会发生滥用行为。
  • @Hi_Daddy - 不要使用*,这样每个人都可以像你说的那样访问它。使用您认为有效的域。
【解决方案2】:

简单的答案:PHP 不受 CORS 的影响。这是浏览器对客户端代码的限制,因此访问的 URL 可以允许或拒绝请求。

【讨论】:

    【解决方案3】:

    您遇到了 CORS,因为您正在从浏览器向不同的域发出 XMLHttpRequest 请求而不是您的页面所在的域。浏览器会阻止它,因为出于安全原因,它通常允许同一来源的请求。当您想要进行跨域请求时,您需要做一些不同的事情。试试这个:http://www.html5rocks.com/en/tutorials/cors/

    如果您只想发起 GET 请求,您可以尝试使用 JSONP datatype="jsonp"。 示例:http://www.sitepoint.com/jsonp-examples/

    【讨论】:

    • 截至目前(2017 年 5 月 26 日)jsonp 不仅是一种黑客攻击,而且也是不安全的。除此之外,它仅适用于 GET 请求。现在不再推荐它,因为有其他干净的替代方案和有效的方法来应对它 (jsonp) 试图解决的挑战。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 2011-12-03
    相关资源
    最近更新 更多