无法使用 Fetch API 获取 JSON,但可以使用 JQuery
Posted
技术标签:
【中文标题】无法使用 Fetch API 获取 JSON,但可以使用 JQuery【英文标题】:Unable to get JSON using Fetch API, but can using 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 来演示吗?见***.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。
【参考方案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 需要重现有效的JSON
在Response.json()
调用时抛出错误。
啊,是的。微妙但重要。【参考方案2】:
302 是一个重定向,因此您的 fetch 请求被重定向到另一个页面,可能是登录页面 (?)
我在您的 fetch 请求中看到您正在使用 credentials:'include'
,这可能包括 Authorization 标头或类似内容,并且您的控制器正在拒绝该请求。
使用 chrome 开发者控制台,如果您在网络选项卡上标记“保留日志”,则可以检查请求
【讨论】:
以上是关于无法使用 Fetch API 获取 JSON,但可以使用 JQuery的主要内容,如果未能解决你的问题,请参考以下文章
Fetch Api 无法从 PHP 服务器获取 Session
html JS.JSON。使用fetch API获取远程JSON数据
使用 fetch、cors 时如何从 json API 获取属性?