jQuery.getJSON - 访问控制允许来源问题

IT技术 javascript jquery json xmlhttprequest access-control
2021-01-19 20:12:37

我正在使用 jQuery 的$.getJSON()函数来返回一组简短的 JSON 数据。

我将 JSON 数据放在一个 url 上,例如example.com. 我没有意识到,但是当我访问同一个 url 时,无法加载 JSON 数据。我跟踪控制台,发现XMLHttpRequest由于Access-Control-Allow-Origin.

现在,我已经通读了很多网站,这些网站都说可以使用$.getJSON(),这将是解决方法,但显然它不起作用。我应该在标题或函数中更改某些内容吗?

非常感谢帮助。

2个回答

很简单,使用$.getJSON()函数,在你的 URL 中只包含

回调=?

作为参数。这会将调用转换为 JSONP,这是进行跨域调用所必需的。更多信息:http : //api.jquery.com/jQuery.getJSON/

这完全取决于服务器接受额外的回调参数,它可能不会在所有情况下都这样做。
2021-03-25 20:12:37
2021-03-26 20:12:37
这在 100% 的情况下都不起作用,就像服务器未设置为服务器 jsonp 一样,它仍然返回 json,您将在其中收到错误消息。
2021-03-27 20:12:37
就我而言,有时我会遇到 CORS 问题,而不是每次打开网站时都会遇到问题。所以现在我已经应用了这个解决方法,但我看不到我是否已经解决了。
2021-04-03 20:12:37

您可能想改用 JSON-P(见下文)。首先快速解释一下。

您提到的标头来自跨源资源共享标准。请注意,人们实际使用的某些浏览器不支持,而在其他浏览器(Microsoft 的,叹气)上,它需要使用特殊对象 ( XDomainRequest) 而不是XMLHttpRequestjQuery 使用的标准它还要求您更改服务器端资源以明确允许其他来源 ( www.xxxx.com)。

要获取您请求的 JSON 数据,您基本上有三个选项:

  1. 如果可能,您可以通过更正正在加载的文件的位置来最大程度地兼容,以便它们与您将它们加载到的文档具有相同的来源。(我假设您必须通过 Ajax 加载它们,因此出现了同源策略问题。)

  2. 使用不受 SOP 约束的JSON-PjQuery 在其ajax调用中内置了对它的支持(只需设置dataType为“jsonp”,jQuery 将完成所有客户端工作)。这需要服务器端更改,但不是很大;基本上,无论您拥有什么生成 JSON 响应,只需查找名为“回调”的查询字符串参数,并将 JSON 包装在将调用该函数的 JavaScript 代码中。例如,如果您当前的 JSON 响应是:

    {"weather": "Dreary start but soon brightening into a fine summer day."}
    

    您的脚本将查找“回调”查询字符串参数(假设该参数的值为“jsop123”)并将该 JSON 包装在 JavaScript 函数调用的语法中:

    jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."});
    

    而已。JSON-P 具有非常广泛的兼容性(因为它通过 JavaScriptscript标签工作)。JSON-P 仅适用于GET,但不是POST(再次因为它通过script标签工作)。

  3. 使用 CORS(与您引用的标头相关的机制)。上面链接的规范中的详细信息,但基本上:

    A. 浏览器将使用OPTIONSHTTP 动词(方法)向您的服务器发送“预检”消息它将包含它将与GET一起发送的各种标头POST以及标头“Origin”,“Access-Control-Request-Method”(例如,GETPOST)和“Access-Control-Request-Headers”(它的标头)想送)。

    B. 您的 PHP 会根据该信息决定请求是否正常,如果正常则以“Access-Control-Allow-Origin”、“Access-Control-Allow-Methods”和“Access-Control-Allow-标头”标头及其允许的值。您不会随该响应发送任何正文(页面)。

    C. 浏览器将查看您的响应,并查看是否允许向您发送实际GETPOST. 如果是这样,它将再次发送该请求,并带有“Origin”和各种“Access-Control-Request-xyz”标头。

    D. 您的 PHP再次检查这些标头以确保它们仍然正常,如果是,则响应请求。

    代码中(我没有做过太多 PHP,所以我不想在这里做 PHP 语法):

    // Find out what the request is asking for
    corsOrigin = get_request_header("Origin")
    corsMethod = get_request_header("Access-Control-Request-Method")
    corsHeaders = get_request_header("Access-Control-Request-Headers")
    if corsOrigin is null or "null" {
        // Requests from a `file://` path seem to come through without an
        // origin or with "null" (literally) as the origin.
        // In my case, for testing, I wanted to allow those and so I output
        // "*", but you may want to go another way.
        corsOrigin = "*"
    }
    
    // Decide whether to accept that request with those headers
    // If so:
    
    // Respond with headers saying what's allowed (here we're just echoing what they
    // asked for, except we may be using "*" [all] instead of the actual origin for
    // the "Access-Control-Allow-Origin" one)
    set_response_header("Access-Control-Allow-Origin", corsOrigin)
    set_response_header("Access-Control-Allow-Methods", corsMethod)
    set_response_header("Access-Control-Allow-Headers", corsHeaders)
    if the HTTP request method is "OPTIONS" {
        // Done, no body in response to OPTIONS
        stop
    }
    // Process the GET or POST here; output the body of the response
    

    再次强调这是伪代码。

@TJCrowder 所以 $.getJSON 不起作用?我们是否需要使用其他方法,如 ajax 并设置标题?
2021-03-17 20:12:37
@TJCrowder 好的.. 你能回答这个问题吗 - stackoverflow.com/questions/22795561/...
2021-03-21 20:12:37
@Mike:哪个“这个”?如果你的意思是 JSON-P,是的,jQuery 在它的ajax调用中支持它我在上面添加了一些细节。如果您的意思是 CORS,那么是的,这是您通过 PHP 设置的标头以响应OPTIONSHTTP 请求并再次响应GETor POST; 我也为此添加了一些细节。但是,如果您有任何机会可以移动文件以使它们具有相同的来源,那么这一切都太过分了。
2021-03-22 20:12:37
@Dinesh:$.getJSON正常工作提供:1)这是一个相同来源的请求,或2)浏览器和服务器都支持CORS和服务器允许的来源,或3)服务器提供了JSON-P接口,你告诉jQuery的你”通过?callback=在您提供的 URL 中使用来重新使用 JSON-P $.getJSON
2021-03-26 20:12:37
有没有办法使用jQuery来做到这一点?或者,是否有我可以设置(通过 PHP)的标题可以让这个工作?
2021-04-11 20:12:37