使用 Fetch API 获取 json 格式的闪烁提要

Posted

技术标签:

【中文标题】使用 Fetch API 获取 json 格式的闪烁提要【英文标题】:Using Fetch API to get flicker feed in json format 【发布时间】:2017-08-10 16:16:39 【问题描述】:

我设法通过使用 $.getJSON 从 flicker feed api 获取 json 响应,但是当我尝试使用 Fetch 进行此操作时,我似乎只获得了 XML 响应。

这行得通:

var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
$.getJSON(flickerAPI, 
                    tags: "searchTerm",
                    tagmode: "any",
                    format: "json"
                )
                .done(function (data) 
                   //....
                );

这不起作用:

var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";

var request = new Request(flickerAPI,  
                mode: 'no-cors',
                tags: 'searchTerm',
                tagmode: 'any',
                format: 'json'
            );

            fetch(request)
                .then(function (res) 
                    return res.json();
                )
                .then(function (text) 
                    console.log(text);
                );

我也想了解为什么在使用 Fetch API 时我会得到: “请求的资源上不存在'Access-Control-Allow-Origin'标头。因此,不允许访问源'null'。如果不透明的响应满足您的需求,请将请求的模式设置为'no-cors'以获取禁用 CORS 的资源。”并且在使用 $.getJSON 时没有。 谢谢!!

【问题讨论】:

我从未使用过 API 或 fetch,但根据文档 flickr.com/services/feeds/docs/photos_public (tags, tagmode, format, ...) 是查询参数,这意味着它们必须在 URL本身,photos_public.gne?format=json&tagmode=any&jsoncallback=...?? 你有没有找到用 fetch() 来做这件事的方法,我现在正在尝试同样的事情并得到同样的错误。希望不必切换到jsonp 【参考方案1】:

简短回答:fetch(…) 方法的参数和fetch(…) 方法的行为与$.getJSON(…) 方法的参数和$.getJSON(…) 方法的行为非常不同——所以你不能指望fetch(…) 做任何类似于 $.getJSON(…) 所做的事情。

更长的答案,回答您的具体问题:

我也想了解为什么我在使用 Fetch API 时 得到:“没有'Access-Control-Allow-Origin'标头出现在 请求的资源……而不是使用 $.getJSON 时。

您的请求 URL 包含子字符串callback=?,所以$.getJSON handles it as JSONP:

如果 URL 包含字符串“callback=?” (或类似的,由服务器端 API 定义),请求被视为 JSONP。

...这意味着在幕后,它不是从 javascript 发送跨域请求,而是创建一个 script 元素来加载 JSONP 响应。由于浏览器允许使用 script 元素跨域加载脚本,因此永远不会遇到任何限制。

但是,当您使用 Fetch API 进行调用时,它不会执行任何幕后魔术来自动将请求识别为基于 URL 的 JSONP 请求,并且不会创建 script 元素加载响应。相反,它只会导致直接向该http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?" URL 发出请求。

http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?" 实际上并不打算与 Fetch API 或 XHR 一起使用,因此它发回的响应不包含 Access-Control-Allow-Origin 响应标头。

根据 CORS 协议,对于浏览器而言,缺少 Access-Control-Allow-Origin 响应标头意味着“不要将此响应暴露给在 Web 应用程序中运行的任何客户端 JavaScript”。 p>

因此,您的浏览器会记录 “请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'null' is not allowed access” 消息,让您知道您的脚本将无法访问响应,以及原因。

如果您设置mode: 'no-cors',我不希望您会看到该消息。但是您基本上永远都不想设置mode: 'no-cors',因为这样做与缺少Access-Control-Allow-Origin 响应标头的效果相同——它完全阻止您的脚本访问响应。


就预期tags: 'searchTerm'tagmode: 'any'format: 'json' 而言,如果您在作为fetch(…) 方法的第二个参数提供的对象中指定它们会产生任何影响,@Yazan 上面的评论是正确的:这些是 flickr API 的自定义查询参数,因此如果您使用 Fetch API 执行 GET 请求,您需要在 URL 中将它们指定为查询参数。

$.getJSON,相比之下,does that for you automatically:

发送到服务器的数据作为查询字符串附加到 URL。

...它所指的数据是您作为第二个参数提供给$.getJSON 的名称/值对的对象。

相比之下,对于fetch(…) 方法,您在第二个参数中指定的名称和值不能是任意查询参数。取而代之的是a predefined set of names are allowed那里:

method:请求方式,如GET、POST。 headers:您想添加到请求中的任何标头 body:您想添加到请求中的任何正文 mode: 请求使用的模式 credentials:您要用于请求的请求凭据 cache: 请求使用的缓存模式 redirect: 使用的重定向模式 referrer:一个 USVString 指定无推荐人、客户端或 URL referrerPolicy:指定referer HTTP header的值 integrity:包含请求的子资源完整性值

【讨论】:

以上是关于使用 Fetch API 获取 json 格式的闪烁提要的主要内容,如果未能解决你的问题,请参考以下文章

在 Javascript/Reactjs 中使用 Fetch API 和 map() 显示 JSON 数据

html JS.JSON。使用fetch API获取远程JSON数据

使用 fetch、cors 时如何从 json API 获取属性?

如何在不使用 JQuery 的情况下使用 fetch API 以 JSON 格式发布表单数据?

无法使用 Fetch API 获取 JSON,但可以使用 JQuery

React Fetch:获取json结果但显示网络错误