jQuery.getJSON – 访问控制 – 允许来源问题
我jQuery的jQuery的$.getJSON()
函数返回一组简短的JSON数据。
我有JSON数据坐在像example.com
这样的url上。 我没有意识到,但是当我访问相同的url时,无法加载JSON数据。 我跟随了控制台,发现XMLHttpRequest
由于Access-Control-Allow-Origin
而无法加载。
现在,我读了很多网站,刚才说的使用$.getJSON()
,这将是周围的工作,但显然这是行不通的。 有什么我应该改变标题或function?
非常感谢帮助。
这很简单,使用$.getJSON()
函数,并在您的url只包括
callback=?
作为参数。 这将转换为JSONP,这是进行跨域调用所必需的。 更多信息: http : //api.jquery.com/jQuery.getJSON/
你可能想使用JSON-P来代替(见下文)。 首先快速解释一下。
您提到的标题来自“ 跨源资源共享”标准。 请注意,某些浏览器不支持实际使用的浏览器,而在其他浏览器(微软的叹息声 )中,它需要使用特殊的对象( XDomainRequest
),而不是使用jQuery使用的标准XMLHttpRequest
。 它还要求您更改服务器端资源以明确允许其他来源( www.xxxx.com
)。
要获取您请求的JSON数据,基本上有三个选项:
-
如果可能的话,您可以通过更正您正在加载的文件的位置来最大程度地兼容,以便它们与您要加载的文件具有相同的来源。 (我假设你必须通过Ajax加载它们,因此出现“ 同源策略”问题。)
-
使用不受SOP约束的JSON-P 。 jQuery在其
ajax
调用中内置了对它的支持(只需将dataType
设置为“jsonp”,jQuery将完成所有客户端工作)。 这需要服务器端的变化,但不是很大的变化; 基本上无论你有什么产生的JSON响应只是寻找一个名为“callback”的查询string参数,并包装在JavaScript代码,将调用该函数的JSON。 例如,如果您当前的JSON响应是:{"weather": "Dreary start but soon brightening into a fine summer day."}
您的脚本会查找“callback”查询string参数(假设参数的值为“jsop123”),并将该JSON封装在JavaScript函数调用的语法中:
jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."});
而已。 JSON-P具有非常广泛的兼容性(因为它通过JavaScript
script
标签工作)。 JSON-P仅用于GET
,但不是POST
(再次因为它通过script
标记工作)。 -
使用CORS(与您所引用的标题相关的机制)。 以上链接的规范中的细节 ,但基本上:
A.浏览器将使用
OPTIONS
HTTP动词(方法)向您的服务器发送“预检”消息。 它将包含它将用GET
或POST
发送的各种标题以及标题“Origin”,“访问控制请求方法”(例如,GET
或POST
)和“访问控制请求标题” (它想要发送的标题)。B.您的PHP根据这些信息决定请求是否正确,如果是,则响应“访问控制允许源”,“访问控制允许方法”和“访问控制允许源”头部“标题,它将允许的值。 你没有发送任何正文(页面)的回应。
C.浏览器会查看你的响应,看看是否允许你发送实际的
GET
或POST
。 如果是这样的话,它将再次发送该请求,并且带有“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
再次强调这是伪代码。