【问题标题】:Cross-origin JSON request跨域 JSON 请求
【发布时间】:2016-06-23 06:51:39
【问题描述】:

我正在为 Twitch.tv 应用程序编写 HTML/CSS/JS。我通过他们的主要API endpoint (api.twitch.tv) 请求(公共、非敏感)数据,但有一条数据尚未集成。但是,此数据可在另一个子域 (tmi.twitch.tv) 中查看。不幸的是,当我进行 $.getJSON 调用(或带有 dataType: JSON 的 $.AJAX)时,我在 Firefox 44.0.2 中收到以下信息:

跨源请求被阻止:同源策略不允许读取位于https://tmi.twitch.tv/{rest of URL} 的远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。

我作为用户知道这种安全机制,但不是作为(新手)程序员。我读了很多书试图管理,但我仍然迷失了。

我收集到的东西: 一个常见的解决方法是请求 JSONP。与 JSON 不同,浏览器不对 JSONP 强制执行跨域策略。我知道主要的 Twitch API 是 JSONP 友好的,并且可能启用了 CORS。相比之下,我想 tmi.twitch.tv 没有启用 CORS。

我尝试过的: 我在我的请求 URL 中附加了 ?callback=?callback=differentStrings?otherQuery=value&callback=differentStrings。这些都不起作用。我将 dataType 更改为 jsonp,并且没有额外的查询字符串(只是更改 dataType 附加了两个查询字符串:callback=jQuery{long number}_{long number} & _={long number},我没有收到 x-origin 块. 但是,我确实得到了以下信息:

语法错误:缺失;声明前 |第 1 行:字符 8

对于我请求的这个对象:

{"hosts":[{"host_id":118084843,"target_id":41981587,"host_login":"politecpu","target_login":"politemaster"},{"host_id":118082906,"target_id":41981587,"host_login":"politerobot","target_login":"politemaster"}]}

我被困住了。我不知道这是否是数据/JSONP 格式的问题,也不知道我是否找到了 x-origin 的解决方法,因为我的成功(-ful 接收数据)功能不起作用。接下来我应该考虑什么?

我想强调一下,我是一个绝对新手(我最近才完成了 JS 和 jQuery 的 Codecademy 课程)。提前感谢您的想法和 cmets。

(编辑)我的功能:

var allHosts = [];  // To be compared against new JSON periodically called via checkHosts()
var getHosts = function() {
	allHosts = [];
	$.ajax({
		url: 'https://tmi.twitch.tv/hosts?include_logins=1&target=' + myID,
		dataType: 'jsonp',
		success: function(data) {
			data.hosts.forEach(function(element) {
				allHosts.push(element.host_id);
			});
			debug('getHosts():', 'data =', data, 'allHosts =', allHosts, 'queue =', queue, 'busy =', busy); // Not relevant
		},
	});
}

【问题讨论】:

  • 它看起来像有效的 JSON。您如何在代码中使用该对象?我认为这就是你的问题所在。
  • 抱歉耽搁了(我在格式化代码时遇到了问题)。我刚刚用它修改了我的问题。 @caszi
  • 相对于 sn-p 的错误是哪一行?会不会是成功对象末尾的逗号?
  • 根据我的 Firefox 控制台,错误实际上是指请求的数据(我很惊讶)。我单击 Firefox 控制台提供的链接,它会打开数据的页面源。
  • 我也应该说我确实尝试删除 'success' 值之后的最后一个逗号,但没有奏效。

标签: jquery json cross-domain


【解决方案1】:

试试这个 - https://api.allowallorigin.com/restapi?url=https://tmi.twitch.tv/hosts?include_logins=1&target=007

我在尝试了多个选项后创建了这个解决方案。同一行的另一个解决方案可以完成这项工作,但会更改 JSON 数据位置,直到有人为此付费。上述服务是免费的,并将继续保持免费。如果人们觉得它有用,那么我可能会放一个主页和一些谷歌广告,否则它应该在可预见的未来继续保持免费。

这是一个示例代码:

jPath.prototype.loadJSONDataFromUrl = function(_url, callback) {
    $.getJSON(_url, function(data) {
        $.fn.jsonData = JSON.stringify(data);
    }).done(function(json){
        if( callback != null) {
            callback();
        }
    }).fail(function(){
        $.getJSON('https://api.allowallorigin.com/allorigin/restapi?url='+_url, function(data) {
            console.log(data);
            console.log(JSON.stringify(data));
            $.fn.jsonData = JSON.stringify(data);
        }).done(function(json){
            if( callback != null) {
                callback();
            }
        });
    });
}

【讨论】:

    【解决方案2】:

    您可以通过在请求中添加标头来完成此操作

    var allHosts = []; // 与通过 checkHosts() 定期调用的新 JSON 进行比较 var getHosts = 函数() { 所有主机 = []; $.ajax({ 网址:'https://tmi.twitch.tv/hosts?include_logins=1&target='+我的ID, 数据类型:'jsonp', 标题:{
    '访问控制允许来源':URLofOrigin
    }, 成功:函数(数据){ data.hosts.forEach(函数(元素){ allHosts.push(element.host_id); }); debug('getHosts():', 'data =', data, 'allHosts =', allHosts, 'queue =', queue, 'busy =', 忙); // 不相干 }, }); }

    【讨论】:

    • 我正在寻找包含标题的语法!谢谢,巴瓦纳。不幸的是,这并没有改变任何东西。当使用dataType: 'jsonp' 请求时,我仍然收到上述语法错误。使用dataType: 'json',我仍然会收到跨域策略消息。这进一步让我相信 tmi.twitch.tv 不支持 CORS。
    【解决方案3】:

    正如herehere 所见,您似乎正在尝试使用 JSONP 访问 JSON 资源。该域不支持 JSONP。

    您可能能够使用服务器端语言来完成您想要的工作,该语言将代表用户获取资源。

    【讨论】:

    • 我非常感谢您的回复,caszi。我仍在阅读您提供给我的两个链接的所有链接。从第二次开始,程序员对与我相同的子域感兴趣,我发现他/她和其他人正在使用其他编程语言。我目前想知道是否应该学习一些 PHP 或 C# 来请求这个 JSON。我也在学习更多关于跨域的知识。我会再回来发帖的。
    • 我学了一点 PHP,虽然我需要一个解释器才能在本地文件中使用它。我选择使用 XAMPP(虽然我不确定这是运行 PHP 的最佳/最轻量级的方式)。我用<?php header('Content-Type: application/json'); echo file_get_contents('http://tmi.twitch.tv/hosts?include_logins=1&target=' . $myID); ?> 制作了一个单独的.php 文件来捕获数据。然后我使用相同的 JavaScript AJAX 调用 (url: localFile.php) 来操作它。再次感谢您让我走上正确的道路,@caszi! :)
    猜你喜欢
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2023-04-03
    • 2017-06-15
    相关资源
    最近更新 更多