jfinal+vue-axios 跨域验证码问题

正题,  

    代码写出来后提示跨域,咋办呢,百度让后就是下面的代码

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers",
				"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

结果是验证码前段能显示了  感觉很简单就解决了  让后接续写

发现验证码输啥都是验证失败   头大

百度了半天没解决  让后群里问问结果最后的答案是百度 - -!想哭有木有

没办法了  找到源码 CaptchaRender 源码看看  发现他是用cookie传的验证码的key然后前端加上这个下面代码

withCredentials :true,

结果出来一坨跟费劲的 报错 

image.png

头疼继续百度   找到了下面这些

一般来说跨域的报错并不是这样,一般是类似于缺少Access-Control-Allow-Origin header的报错。

因为我用的是Vue,就先在vue.config.js的devServer options里配置了proxy,但是没什么效果;后来配置了nginx进行转发,仍然是这个报错,甚至一度让我怀疑我的nginx配置……当然事实上是没错的。而且,我问过后端之后,听说已经配置了cors,按理说不应该报错,这就让我感觉更神秘了。


回去查了一遍代码,发现我在axios里设置了withCredentials: true。看到网上有人这么说:


withCredentials的情况下,后端要设置Access-Control-Allow-Origin为你的源地址,例如http://localhost:8080,不能是*,而且还要设置header(‘Access-Control-Allow-Credentials: true’);


说白了就是后端没允许cookie过去……


另外,Access-Control-Allow-Origin设置为*时cookie不会出现在http的请求头里,所以报错里说Access-Control-Allow-Origin不能是*也是有道理的。


此外还有一个问题,OPTIONS请求无法通过。我们知道,OPTIONS请求是因为前端发送了“非简单请求”,比如Content-Type: 'application/json',如果后端失误(或者根本不知道有OPTIONS这种请求),就有可能把OPTIONS挡住,导致无法通过。在不修改后端的情况下,也是有办法解决这个问题的,就是调整Content-Type: 'application/x-www-form-urlencoded',同时将传输的JSON进行一次序列化(可以用querystring进行转换),这样也能解决问题。



让后右百度了一下最后的解决代码

后端  这个也是百度的  找不见链接了

//允许跨域的域名,*号为允许所有,存在被 DDoS攻击的可能。
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
//表明服务器支持的所有头信息字段
response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma,Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
//如果需要把Cookie发到服务端,需要指定Access-Control-Allow-Credentials字段为true;
response.setHeader("Access-Control-Allow-Credentials", "true");
// 首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用 POST, GET 和 OPTIONS 方法发起请求。
//该字段与 HTTP/1.1 Allow: response header 类似,但仅限于在需要访问控制的场景中使用。
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
//表明该响应的有效时间为 86400 秒,也就是 24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。
//请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。
response.setHeader("Access-Control-Max-Age", "86400");
// IE8 引入XDomainRequest跨站数据获取功能,也就是说为了兼容IE
response.setHeader("XDomainRequestAllowed","1");

前端

withCredentials :true,
headers:{
    'Content-Type':'application/x-www-form-urlencoded'
}


问题是解决了 但是看了好多资料感觉这么解决有点投机取巧一样  哎。 大神指点一下

下面附链接

axios设置withCredentials导致“跨域”的解决方案

评论区

JFinal

2019-12-07 11:17

前端的事挺多,解决起来麻烦,楼主的探索精神值得学习,赞

linjiahao

2019-12-08 19:44

野?

lyq027

2019-12-09 08:21

vue直接用proxy就行,不用后端额外代码。最好再看看vue的proxy怎么用,有没有写错

linjiahao

2019-12-12 19:36

你这样写的话每个方法里都得加这个很麻烦,vue 里写个vue.config.js 写了个proxy 设置个api(后台的url) 设置跨域为true 需要的时候调用这个api就可以了,后端不用设置的。

15386747521

2019-12-16 10:45

@linjiahao vue的跨域也可以抽出来统一设置这个头啊 虽然我也已经改成了config里配置 不过这个方法是可以用的

rirai

2020-04-27 15:36

我也遇到了同样的问题,我的解决代码如下:
//允许跨域访问的域名,若有端口需要写全(协议+域名+端口),若没有端口末尾不用加'/'
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE,OPTIONS");
//允许前端带认证Cookie,启用此项后,上面的域名不能为*,必须制定具体的域名,否则浏览器会提示
response.setHeader("Access-Control-Allow-Credentials","true");
//提示OPTION预检时,后端需要设置的两个常用自定义头
response.setHeader("Access-Control-Allow-Headers","Content-Type,X-Requested-With,withCredentials");