【问题标题】:Unable to get JSON using Fetch API, but can using JQuery无法使用 Fetch API 获取 JSON,但可以使用 JQuery
【发布时间】:2018-03-17 17:53:35
【问题描述】:

我正在将一个 React 项目集成到一个 Grails/Angular 系统中,并且我正在尝试使用来自 React 的 Fetch API 来查询 Grails。

在应用程序运行和 Chrome 开发者工具控制台打开的情况下,以下操作按预期工作:

$.get('/project/controller/get', function(data, status) {
  console.log(data); 
});

它会显示一堆 JSON,如下所示:

以下内容无法按预期工作:

fetch('/project/controller/get', {
    credentials: 'include',
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(response => response.json())
.then(response => console.log(response))
.catch(error => console.log(error))

它给出了一个语法错误,因为它试图将 HTML 文档解析为 JSON。

在开发者工具网络选项卡中,我看到当我发出 JQuery 请求时,只有一个 GET 请求,而服务器响应是我想要的 JSON。

当我使用 Fetch API 发出请求时,会出现两个请求:

  • 一个到 /project/controller/get,它只响应状态码 302,没有 JSON
  • /project 的另一个响应状态码为 200,以及应用程序首页的 HTML。这是 Fetch API 接收并尝试解析为 JSON 的内容。

在执行 render as JSON 语句之前,我可以验证 Grails 控制器方法是否按预期生成数据。

使用 Axios 也会发生同样的事情。

JQuery 请求详情:

一般

请求网址:http://localhost:8080/project/controller/get

请求方法:GET

状态码:200 OK

远程地址:[::1]:8080

Referrer Policy:no-referrer-when-downgrade

响应标头

HTTP/1.1 200 正常

服务器:Apache-Coyote/1.1

内容类型:text/html;charset=utf-8

传输编码:分块

日期:格林威治标准时间 2017 年 10 月 6 日星期五 02:41:59

请求标头

GET /project/controller/get HTTP/1.1

主机:本地主机:8080

连接:保持活动

接受:/

X-Requested-With: XMLHttpRequest

用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如 Gecko)Chrome/61.0.3163.100 Safari/537.36

推荐人:http://localhost:8080/project/settings/

接受编码:gzip、deflate、br

接受语言:en-GB,en;q=0.8,en-US;q=0.6,fr;q=0.4,ru;q=0.2

Cookie:JSESSIONID=52F86C47C43F558E05C2F6DB5E9E7CE2

有什么办法可以让它工作吗?谢谢。


我刚刚注意到在浏览器中输入 http://localhost:8080/project/controller/get 会自动将我重定向到 http://localhost:8080/project 出于某种原因。可能是服务器做了一些奇怪的事情,但奇怪的是 JQuery 请求有效......

【问题讨论】:

  • Content-Type header 用于指定请求正文的数据类型。由于您正在发出获取请求,因此您不需要它。尝试删除它。
  • “它给出了一个语法错误,因为它试图将 HTML 文档解析为 JSON。” 你能创建一个 jsfiddle jsfiddle.net 或 plnkr plnkr.co 来演示吗?见stackoverflow.com/help/mcve
  • 代码是否可能使用jQuery.ajaxSetup() 为Ajax 请求设置默认值?无论如何,对于您的 fetch 请求,您是否尝试过使用 headers: { 'Accept': 'application/json' } 或它的一些变体? (也就是说,为 GET 请求设置 Accept 标头,而不是为其设置 Content-Type ——正如前面评论中所指出的那样,这不会有任何影响。)当您在浏览器中查看请求的 devtools 时, jQuery $.get 调用正在发送,它发送的是什么 Accept 标头?
  • 另外,您的 jquery 示例查询的 url 与您的 fetch 示例不同:
  • 将标题更改为headers: { 'Accept': 'application/json'} 不会影响它。它仍然返回 HTML。

标签: javascript jquery grails fetch-api


【解决方案1】:

它给出了一个语法错误,因为它试图解析一个 HTML 文档 作为 JSON。

如果响应是 HTML 使用 Response.text()

【讨论】:

  • 是的,但问题是如何让它返回 JSON,因为通过 jQuery $.get() 查询相同的 URL 确实 返回 JSON。
  • @nnnnnn "假设通过 jQuery $.get() 查询相同的 URL 确实返回 JSON" 我们如何确定 "application/json" 已提供服务?如果响应是有效的JSON,OP 为什么会提到 HTML 文档?
  • 该问题明确指出,对同一 URL 的请求会产生不同的响应,具体取决于它们使用的是 $.get() 还是 fetch()。他们还在控制台网络选项卡中看到不同的行为。这就是问题的全部意义所在。
  • @nnnnnn 不,这不是问题的重点。 OP 在问题文本中明确提到了 HTML document。 HTML 文档与JSON 有什么关系? OP 需要重现有效的JSONResponse.json() 调用时抛出错误。
  • 啊,是的。微妙但重要。
【解决方案2】:

302 是一个重定向,因此您的 fetch 请求被重定向到另一个页面,可能是登录页面 (?)

我在您的 fetch 请求中看到您正在使用 credentials:'include',这可能包括 Authorization 标头或类似内容,并且您的控制器正在拒绝该请求。

使用 chrome 开发者控制台,如果您在网络选项卡上标记“保留日志”,则可以检查请求

【讨论】:

    猜你喜欢
    • 2021-10-01
    • 2020-05-31
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多