最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】reactjs中fetch调用接口出错:TypeError: Failed to fetch

ReactJS crifan 30027浏览 0评论

折腾:

【已解决】chrome中调用api出错:Failed to load Response for preflight has invalid HTTP status code 403

之后,服务器端已经确保支持了OPTIONS了:

Access-Control-Allow-Headers →origin, Content-type, accept, x-requested-with, sid, mycustom, smuser

Access-Control-Allow-Methods →GET, POST, PUT, DELETE, OPTIONS

Access-Control-Allow-Origin →*

Content-Disposition →inline;filename=f.txt

Content-Encoding →gzip

Content-Type →application/json;charset=UTF-8

Date →Tue, 26 Jun 2018 11:55:44 GMT

Server →Apache-Coyote/1.1

Transfer-Encoding →chunked

Vary →Accept-Encoding

结果js中调试返回还是出错:

call path http://ip:port/xmt-web/getUserDetail.do -> res= {code: -9999, message: TypeError: Failed to fetch}

store.js?adc6:185 fetch path=getUserDetail.do with params={"method":"POST","headers":{"Content-Type":"application/json"},"body":"{\"accessToken\":\"cxxxa\",\"clientId\":\"0xxxaebd\",\"sign\":\"xxx\"}"} error code=-9999 message=TypeError: Failed to fetch, data=undefined

去搜:

TypeError: Failed to fetch

不过,突然感觉,或许是:

前面的:

Content-Type →application/json;charset=UTF-8

不符合此处的:

request中,没有加上:

‘Accept’: ‘application/json’

甚至是:

‘Accept’: ‘application/json;charset=UTF-8

?

先去搜搜看:

js fetch TypeError: Failed to fetch

Valid response returning "TypeError: Failed to fetch" · Issue #3403 · swagger-api/swagger-ui

javascript – Uncaught (in promise) TypeError: Failed to fetch and Cors error – Stack Overflow

Fetch进阶指南 | louis blog

“same-origin: 表示同域下可请求成功; 反之, 浏览器将拒绝发送本次fetch, 同时抛出错误 “TypeError: Failed to fetch(…)”.”

加上mode参数,试试:

  • same-origin

  • cors

  • cors-with-forced-preflight

  • no-cors

javascript – TypeError: Failed to fetch – Stack Overflow

javascript – Fetch API yields "TypeError: failed to fetch" – Stack Overflow

javascript – JS fetch TypeError: Failed To Fetch – Stack Overflow

"TypeError: Failed to fetch" for valid response – Bugs and errors – Tyk Community Forum

Fetch is the new XHR – GauntFace | Matthew Gaunt

【已解决】js中fetch设置mode为no-cors出错:SyntaxError Unexpected end of input

另外试了:

换成:

"mode":”cors"

或:

mode: "same-origin"

结果错误依旧:

message=TypeError: Failed to fetch

换成:

mode: "cors-with-forced-preflight"

结果:

message=TypeError: Failed to execute ‘fetch’ on ‘Window’: Invalid mode,

试了:

        method : "POST",

        // mode: "no-cors",

        // mode: "cors",

        // mode: "same-origin",

        // mode: "cors-with-forced-preflight",

        headers : {

          ‘Content-Type’: ‘application/json’,

          // mode: "no-cors"

          ‘Accept’: ‘application/json;charset=UTF-8’

        },

都不行。

然后发现,其实在此处的:

TypeError: Failed to fetch

错误之前的根本错误其实是:

OPTIONS  403 Forbidden

的问题,所以要去解决:

【已解决】js中用fetch的POST访问服务器端接口出错:OPTIONS  403 Forbidden

另外去了解一下:

http://ip:port/xmt-web/getUserDetail.do

的:

api 接口 do后缀

从微信支付宝支付接口设计谈API接口产品的设计经验和最佳实践 – 简书

Swagger UI URL 添加自定义后缀 .do – Simon_1988的个人空间 – 开源中国

“Spring boot.”

SpringMVC 返回字符串 – CSDN博客

“@RequestMapping(value=”twoB.do”)”

接口 – CSDN博客

->感觉像是:

java后的后台,有些api接口是用do的后缀的

后来,果然是服务器端去做了些修改

  • 之前:

    • 服务器是支持跨域访问,不支持预请求

    • 原生js访问是没有采取预请求,只是vue-resouce采用了

  • 现在:已支持预请求

    • 改动是:后台设置响应options

然后就支持了CORS:

然后APP端就可以正常获取数据了:

【总结】

此处,app端内部的webview中js的POST,出错:

Chrome:

OPTIONS 403 (Forbidden)

-》

TypeError: Failed to fetch

Safari中:

[Error] Failed to load resource: Preflight response is not successful

经过大量的调试,包括试了:

  • POST时,加上mode参数,试了各种值

    • same-origin

    • cors

    • cors-with-forced-preflight

    • no-cors

  • 换了其他http库:Axios

    • 同样错误

最终确定了是:

服务器端本身不支持CORS,不支持正常的Preflight request

解决办法是:

  • APP端:

    • 不需要做任何事情

    • 对于CORS问题,也没法做任何事情

  • 服务器端

    • 加了OPTIONS的支持

    • 从而支持了CORS

    • 支持了预请求

服务器端的代码改动是:

response.setHeader("Access-Control-Allow-Origin", "*");

response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");

response.setHeader("Access-Control-Allow-Headers", "Authorization,Content-type,Accept,X-Requested-With,sid,mycustom,smuser,Origin");

response.setHeader("Access-Control-Max-Age", "3600");

response.setHeader("Access-Control-Allow-Credentials", "true");

HttpServletRequest httpRequest = (HttpServletRequest) request;

HttpServletResponse httpResponse = (HttpServletResponse) response;

if ( httpRequest.getMethod().equals("OPTIONS") ) {

    httpResponse.setStatus(HttpServletResponse.SC_OK);

    return;

}

filterChain.doFilter(request, response);

-》类似其他的帖子可供参考:

HttpServletRequest Access-Control-Allow-Origin

java – Origin is not allowed by Access-Control-Allow-Origin – how to enable CORS using a very simple web stack and guice – Stack Overflow

servlet过滤器实现跨域Access-Control-Allow-Origin – CSDN博客

To enable CORS support in Spring MVC 4 – Access-Control-Allow-Origin

Java CORS Filter Example – HowToDoInJava

【Access-Control-Allow-Origin】跨域问题 – panie2015 – 博客园

SpringMVC 跨域请求 – 苦今生修来世 – ITeye博客

-》使得app端中js的POST就可以正常获取数据了。

转载请注明:在路上 » 【已解决】reactjs中fetch调用接口出错:TypeError: Failed to fetch

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
90 queries in 0.193 seconds, using 22.12MB memory