折腾:

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

872c25f70d915d8767f88135acf9089f.png

9a472cdab189cad9bb3ae366daef8bd4.png

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中调试返回还是出错:

c30df3e81405031b465055fab814830b.png

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

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

加上mode参数,试试:same-origin

cors

cors-with-forced-preflight

no-cors

另外试了:

换成:

"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

的问题,所以要去解决:

另外去了解一下:

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

的:

api 接口 do后缀

“Spring boot.”

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

->感觉像是:

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

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

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

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

现在:已支持预请求

改动是:后台设置响应options

然后就支持了CORS:

8930b212478488acd47c1098f238bdcb.png

e8151372ef01efb53ccea9269e604f84.png

70dc050cec9dd8074f9517fe64e5cd81.png

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

ed647fce468e62396260b11762f6309e.png

【总结】

此处,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

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

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐