【问题标题】:Using Fetch API to get flicker feed in json format使用 Fetch API 获取 json 格式的闪烁提要
【发布时间】: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

标签: javascript json cors fetch-api flicker


【解决方案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:包含请求的子资源完整性值

【讨论】:

    猜你喜欢
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 2017-12-10
    • 1970-01-01
    相关资源
    最近更新 更多