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

Using Fetch API to get flicker feed in json format

我设法通过使用 $.getJSON 从闪烁提要 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 时我得到: "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled." 并且在使用 $.getJSON 时没有。 谢谢!!

简短回答:fetch(…) 方法的参数和 fetch(…) 方法的行为与 $.getJSON(…) 方法的参数和 [=12] 的行为有很大不同=] 方法——所以你不能指望 fetch(…) 会像 $.getJSON(…) 那样做任何事情。

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

I also would like to understand why when using the Fetch API i am getting: "No 'Access-Control-Allow-Origin' header is present on the requested resource… and when using $.getJSON not.

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

If the URL includes the string "callback=?" (or similar, as defined by the server-side API), the request is treated as JSONP instead.

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

但是,当您使用 Fetch API 进行调用时,这不会执行任何 behind-the-scenes 魔法来自动将请求识别为基于 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 响应 header.

根据 CORS 协议,对于浏览器而言,缺少 Access-Control-Allow-Origin 响应 header 意味着 “不要将此响应公开给任何 client-side JavaScript 运行 在网络应用中”.

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

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


就预期 tags: 'searchTerm'tagmode: 'any'format: 'json' 如果您在 object 中指定它们作为第二个参数给出fetch(…) 方法,@Yazan 上面的评论是正确的:这些是​​ flickr API 的自定义查询参数,因此如果您使用 Fetch API 执行 GET 请求,则需要指定它们在 URL 作为查询参数。

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

Data that is sent to the server is appended to the URL as a query string.

…这里的数据意味着 name/value 对中的 object 作为第二个参数提供给 $.getJSON.

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

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