博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一次跨域请求出现 OPTIONS 请求的问题及解决方法
阅读量:6861 次
发布时间:2019-06-26

本文共 2186 字,大约阅读时间需要 7 分钟。

问题背景:

浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域 在前后端开发过程经常会遇到跨域问题。

前端这边是一个get请求,按理说也没啥,但是在请求的header里面要添加两个自定义的header。

GET http://localhost:8080/api/v1/usersAccept: */*Content-Type: application/jsonAuthorization: token:21232f297a57a5a743894a0e4a801fc3Username: admin

  增加了两个自定义字段 Authorization和Username 在请求时 我看到 network里面出现了两次请求记录 第一次是一个 OPTION请求 状态码200第二次是我的get请求 状态码 401。

可以这边后端已经做了CORS处理。为何还出现这种情况呢。 我们一般在项目里解决跨域问题简单说会采取方案有:

  1. 使用ajax直接跨域访问 2.使用JsonP。实际使用时,由于JsonP向Server提交URL的长度限制在8000字符,超过了则被浏览器拒绝,因此不采用。

对于第一种方案,后端需要做的工作是: 接口允许允许跨域请求:

header('Access-Control-Allow-Origin:*');  //支持全域名访问,不安全,部署后需要限制为R.comheader('Access-Control-Allow-Methods:POST,GET,OPTIONS,DELETE'); //支持的http动作header('Access-Control-Allow-Headers:x-requested-with,content-type');  //响应头 请按照自己需求添加。

  前端发起跨域请求:就是正常的$.ajax请求即可。项目用的vue全家桶 用的axios 发送的请求:

// request拦截器service.interceptors.request.use(  config => {    if (store.getters.token) {      config.headers['Authorization'] =`token:${getToken()}`       config.headers['Username'] =`getUsername()`    }    return config  },  error => {    // Do something with request error    Promise.reject(error)  })

  

但是,碰到个问题,国内网站基本没有讲,就是option请求问题。

在正式跨域的请求前,浏览器会根据需要,发起一个“PreFlight”(也就是Option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源,或者域),还有是否需要Credentials(认证信息) 三种场景:

  1. 如果跨域的请求是Simple Request(简单请求 ),则不会触发“PreFlight”。Mozilla对于简单请求的要求是: 以下三项必须都成立:

  2. 只能是Get、Head、Post方法

  3. 除了浏览器自己在Http头上加的信息(如Connection、User-Agent),开发者只能加这几个:Accept、Accept-Language、Content-Type、。。。。

  4. Content-Type只能取这几个值: application/x-www-form-urlencoded multipart/form-data text/plain

XHR对象对于HTTP跨域请求有三种:简单请求、Preflighted 请求、Preflighted 认证请求。简单请求不需要发送OPTIONS嗅探请求,但只能按发送简单的GET、HEAD或POST请求,且不能自定义HTTP Headers。Preflighted 请求和认证请求,XHR会首先发送一个OPTIONS嗅探请求,然后XHR会根据OPTIONS请求返回的Access-Control-*等头信息判断是否有对指定站点的访问权限,并最终决定是否发送实际请求信息。 那么我的get请求呢? 原来,产生 OPTIOINS 请求的原因是:自定义 Headers 头信息导致的。 浏览器会去向 Server 端发送一个 OPTIONS 请求,看 Server 返回的 "Access-Control-Allow-Headers" 是否有自定义的 header 字段。因为我之前没有返回自定义的字段,所以,默认是不允许的,造成了客户端没办法拿到数据。

那么这样 的话如果后端是python的话

from corsheaders.defaults import default_headersCORS_ALLOW_HEADERS = default_headers + (    'Authorization,Username')

  

转载于:https://www.cnblogs.com/xiaozengzeng/p/10852224.html

你可能感兴趣的文章
【转】Linux mysql停止失败的解决办法 Stopping MySQL database server mysqld [fail]
查看>>
tomcat8配置tomcat-users.xml不生效
查看>>
splay树入门(带3个例题)
查看>>
CentOS 6.9使用iptables搭建网关服务器(转)
查看>>
MySQL学习笔记(二)
查看>>
Kafka的生产者和消费者代码解析
查看>>
Intellij Idea编译项目下的.java文件时的编码问题
查看>>
【深度学习系列】PaddlePaddle可视化之VisualDL
查看>>
[离散时间信号处理学习笔记] 11. 连续时间信号的采样与重构
查看>>
python os.system()和os.popen()
查看>>
Tensorflow1.4 高级接口使用(estimator, data, keras, layers)
查看>>
Unix环境高级编程(四)数据系统文件和信息
查看>>
孟晓阳:IT运行监控系统设计与使用心得
查看>>
Navicat Premium 12.0.18安装与激活(转)
查看>>
Chart:Amcharts
查看>>
查看mysql服务器连接
查看>>
jquery是什么
查看>>
Yii之路(第八)
查看>>
[UWP小白日记-2]SQLite数据库DOME
查看>>
spring + Mybatis + pageHelper + druid 整合源码分享
查看>>