再遇CORS -- 自定义HTTP header的导致跨域

指路牌

  • 后端配置好了跨域,但是前端在HTTP header添加token后,又产生跨域的问题
  • Flask、Vue(Axios)、跨域

适用场景

  • 前后端分离,想要使用token来管理登录状态,或调用后台接口

环境

  • 平台无关

参考博客

背景

出于多种考虑,放弃了使用类似WordPress这种现成博客解决方案,准备自己搭建一个博客系统,技术选型为:后端:Flask,前端:Vue。登录状态管理放弃cookie,采用token。开发进行到路由保护处时出现了CORS的问题,具体情形是Vue将从后台获取的token添加到HTTP请求的header中,调用相应接口时出现跨域。

在此次跨域出现前实际上已经在Flask通过flask_cors配置了跨域解决方案,因此跨域的产生是让我十分不解的,又由于问题比较奇特在搜索引擎中没有找到很好的解决方案(也可能是我不知道怎么描述,没有搜出来),因此自己重新研究可以一下跨域,又有了一些新收获。

分析

相信使用前后端分离的开发者在开发之初就会碰到跨域的问题,跨域的解决方案有很多种,我选择通过后台解决。

跨域是浏览器同源策略导致的问题,网上相关文章很多,此处不赘述。备注一点:postman不会产生跨域。

Flask解决跨域的方案非常简单,以下代码即可完成。

from flask_cors import CORS
CORS(app,supports_credentials=True

@app.after_request
def after_request(resp):
    resp = make_response(resp)
    resp.headers[‘Access-Control-Allow-Origin‘] = ‘http://127.0.0.1:8080‘
    resp.headers[‘Access-Control-Allow-Methods‘] = ‘GET,POST‘
    resp.headers[‘Access-Control-Allow-Headers‘] = ‘x-requested-with,content-type‘
    return resp

配置完成后,一直也没有没有出过问题,因此也就没有去进一步了解其配置的含义,直到这一次被卡住,让我不得不去了解一下跨域我究竟配置了什么东西?

其实这个问题的关键点就在于那三条配置:Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers.
他们到底代表什么含义?

首先Access-Control-Allow-Origin,字面上的意思,配置这个可以允许相应的源来访问后台资源,网上大多在此处的写的是*,也即允许所有源,这样很不安全,由于我此处是本地开发阶段,Vue的启动端口是8080,所以我写的是http://127.0.0.1:8080,根据你的开发需要改成自己需要的三元组即可。

其次Access-Control-Allow-Methods,也是字面上的意思,允许用的HTTP的Method有哪些,GET,POST是最常见的,此处只写了两个,如果你需要使用其他Method,在这里要写进来,否则也会会出现跨域问题。

以上两个配置都没有问题,问题在了最后一部分:

Access-Control-Allow-Headers,和上面两个一样,字面的意思,之所以是她出问题了,是因为我们在前端给HTTP请求添加了一个自定义的字段token,而这不在许可范围内(许可的只有x-requested-withcontent-type ),因此被判定为了不符合同源策略的非法请求,所以我们只需要将自定义的header添加进去即可。答案已经出来了。

继续挖一下,这个字段的两个含义分别还是什么?x-requested-with,content-type.

x-requested-with是一个用来判断客户端请求是否由Ajax发起的,所以和Axios有什么关系?答案是:没有关系...可以直接删了。贴上这段代码的人或者是默认了发起请求使用的是Ajax,又或者没有分析字段含义,所以很直接贴了这段代码,但是对于使用Axios的开发者来说,这个字段不是必然的。

content-type: 指明POST请求的数据格式以及编码方式。数据格式最常见的莫过于josn,其形式如下:application/json在后端打印出POST请求的HTTP Header,就会发现有下面这条和数据。

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

解决方案

Access-Control-Allow-Headers中添加上自定义的header名称,整体如下:

from flask_cors import CORS
CORS(app,supports_credentials=True

@app.after_request
def after_request(resp):
    resp = make_response(resp)
    resp.headers[‘Access-Control-Allow-Origin‘] = ‘http://127.0.0.1:8080‘
    resp.headers[‘Access-Control-Allow-Methods‘] = ‘GET,POST‘
    resp.headers[‘Access-Control-Allow-Headers‘] = ‘content-type,token‘
    return resp

其实直接删掉Access-Control-Allow-Headers这条配置,也能解决问题,但是枚举出所有固定情形当然是更安全的。

####
要获取更多Haytham原创文章,请关注公众号"许聚龙":

原文地址:https://blog.51cto.com/13852791/2438064

时间: 2024-11-01 16:24:30

再遇CORS -- 自定义HTTP header的导致跨域的相关文章

(转)跨域的另一种解决方案——CORS(Cross-Origin Resource Sharing)跨域资源共享

在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片或者脚本.但是Javascript脚本是不能获取这些资源的内容的,它只能被浏览器执行或渲染.主要原因还是出于安全考虑,浏览器会限制脚本中发起的跨站请求.(同源策略, 即JavaScript或Cookie只能访问同域下的内容).跨域的解决方案有多重JSONP.Flash.Iframe等,当然还有COR

跨域的另一种解决方案CORS(CrossOrigin Resource Sharing)跨域资源共享

在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片或者脚本.但是Javascript脚本是不能获取这些资源的内容的,它只能被浏览器执行或渲染.主要原因还是出于安全考虑,浏览器会限制脚本中发起的跨站请求.(同源策略, 即JavaScript或Cookie只能访问同域下的内容).跨域的解决方案有多重JSONP.Flash.Iframe等,当然还有COR

跨域的另一种解决方案——CORS(Cross-Origin Resource Sharing)跨域资源共享

在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片或者脚本.但是Javascript脚本是不能获取这些资源的内容的,它只能被浏览器执行或渲染.主要原因还是出于安全考虑,浏览器会限制脚本中发起的跨站请求.(同源策略, 即JavaScript或Cookie只能访问同域下的内容).跨域的解决方案有多重JSONP.Flash.Iframe等,当然还有COR

记录:使用springboot的cors和vue的axios进行跨域

一.编写一个配置类,并且注册CorsFilter: 注意允许跨域的域名不要写错 @Configuration public class ZysuyuanCorsConfiguration { @Bean public CorsFilter corsFilter() { // 初始化cors配置对象 CorsConfiguration corsConfiguration = new CorsConfiguration(); // 允许跨域的域名,如果要携带cookie,不能写*,*代表所有域名都可

C#API解决自定义请求头下的跨域问题

解决方法一: public class CrosHandler : DelegatingHandler { private const string Origin = "Origin"; private const string AccessControlRequestMethod = "Access-Control-Request-Method"; private const string AccessControlRequestHeaders = "A

循序渐进Python3(十一) --6--  Ajax 实现跨域请求 jsonp 和 cors

Ajax操作如何实现跨域请求? Ajax (XMLHttpRequest)请求受到同源策略的限制. Ajax通过XMLHttpRequest能够与远程的服务器进行信息交互,另外XMLHttpRequest是一个纯粹的Javascript对象,这样的交互过程,是在后台进行的,用户不易察觉. 因此,XMLHTTP实际上已经突破了原有的Javascript的安全限制. 举个例子: 假设某网站引用了其它站点的javascript,这个站点被入侵并在javascript中加入获取用户输入并通过ajax提交

CORS跨域资源共享你该知道的事儿

"唠嗑之前,一些客套话" CORS跨域资源共享,这个话题大家一定不陌生了,吃久了大转转公众号的深度技术好文,也该吃点儿小米粥溜溜胃里的缝儿了,今天咱们就再好好屡屡CORS跨域资源共享这个话题,大牛怡情小牛巩固,把这碗前端经久不凉的大碗茶,再细细的品一品. "JSONP直接了当很豪爽,CORS细吮慢品大补汤" 在咱们前端的日常工作中,跨域比较常用的方式就是JSONP,JSONP呢就是通过script标签无同源限制的特点,在获取到需要的资源后自动执行回调方法的方式,而我

客户端ajax请求为实现Token验证添加headers后导致正常请求变为options跨域请求解决方法

客户端为了实现token认证,通过Jquery的ajaxSetup方法全局配置headers: 全局配置headers后会导致部分不需要token认证的请求变为options请求,导致跨域访问.报错信息如下: CORS概念 支持CORS请求的浏览器一旦发现ajax请求跨域,会对请求做一些特殊处理,对于已经实现CORS接口的服务端,接受请求,并做出回应. 有一种情况比较特殊,如果我们发送的跨域请求为"非简单请求",浏览器会在发出此请求之前首先发送一个请求类型为OPTIONS的"

Web CORS 跨域方式使用方式

CORS 参考 http://enable-cors.org/index.html https://help.aliyun.com/document_detail/oss/practice/cors_guide.html 同源策略 跨域访问,或者说JavaScript的跨域访问问题,是浏览器出于安全考虑而设置的一个限制,即同源策略.当来自于A网站的页面中的JavaScript代码希望访问B网站的时候,浏览器会拒绝该访问,因为A,B两个网站是属于不同的域. 在实际应用中,经常会有跨域访问的需求,比