一次跨域请求出现 OPTIONS 请求的问题及解决方法

问题背景:

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

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

GET http://localhost:8080/api/v1/users
Accept: */*
Content-Type: application/json
Authorization: token:21232f297a57a5a743894a0e4a801fc3
Username: admin

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

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

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

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

header(‘Access-Control-Allow-Origin:*‘);  //支持全域名访问,不安全,部署后需要限制为R.com
header(‘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_headers

CORS_ALLOW_HEADERS = default_headers + (
    ‘Authorization,Username‘
)

  

原文地址:https://www.cnblogs.com/xiaozengzeng/p/10852224.html

时间: 2024-08-07 08:54:29

一次跨域请求出现 OPTIONS 请求的问题及解决方法的相关文章

springboot shiro 前后端分离,解决跨域、过虑options请求、shiro管理session问题、模拟跨域请求

一.解决跨域.过虑options请求问题 1.创建过虑类 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; im

http跨域时的options请求

1.背景 在前后端分离的项目中经常会遇到跨域请求的问题,如果没有进行跨域配置,会浏览器请求失败.我一般采用两种解决方案: 1.采用nginx进行转发,是前后端服务处于同一个域下面,从根本上避免跨域问题. 2.后端服务做一些配置,允许请求跨域,从而解决浏览器跨域问题.但是有时候浏览器还会发送OPTIONS请求. 2.跨域请求 跨域请求的介绍,以及处理方式可以看https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS,说的非常详细 简单说就是,浏览

跨域GET、POST请求

跨域GET.POST请求的小结 重点:跨域POST大量数据: JQuery:$.ajax/$.getJSON支持jsonp格式的跨域,但是只支持GET方式,暂不支持POST: CORS:w3c关于跨域的新方案,res.setHeader('Access-Control-Allow-Origin','*'),兼容IE9+: so,跨域POST是个值得研究的问题啊!万能的JQuery无法跨域POST:鉴于基本国情,CORS也只是适合在移动端玩玩: 相信有同学这样做过: 1 $.ajax({ 2 ty

【jquery】ajax 请求成功后新开窗口被拦截解决方法

问题: 前面开发项目时碰到一个问题,ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但是很可惜被浏览器给拦截了,怎么解决这个问题呢? 分析: 浏览器之所以拦截新开窗口是因为该操作并不是用户主动触发的,所以它认为这是不安全的就拦截了(不过如果是 _self 的话就不会有这个限制),即使 ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('click')),浏览器也会认为不是由用户主动触发的,因此不能被安全执行,所

【转】drupal7请求异常,执行时间过长的解决方法

drupal7请求错误,执行时间过长的解决办法 根据你的系统或网络设置Drupal不能读取网页,造成功能缺失.可能是web服务器配置或PHP设置引起的,可用更新.获取更新源.使用OpenID登 录或使用其他网络服务的下载信息都需要解决这个问题.若确定Drupal可正常读取网页但仍然出现此消息,你可以在你的 settings.php 文件底部添加 $conf['drupal_http_request_fails'] = FALSE;. Your Status report page located

小程序云开发调用HTTP请求中got第三方库使用失败解决方法

小程序云开发调用HTTP请求中got第三方库使用失败解决方法 错误代码 {"errorCode":1,"errorMessage":"user code exception caught","stackTrace":"The \"original\" argument must be of type function"} 替换方案 // 云函数入口文件 const cloud = req

当跨域时,js ajax 请求出现options请求

上面有文章说过http的options. 查了很久.试了很多版本的jQuery,下面这段代码在同事的机子上测试是没有问题的.正常 的请求, 一在我机子上面就会出现option,网上说先向服务器预检等.为什么在同事的机子上面是正常的呢..最后查出原因.是我在html页面还引入了一个全局的js文件,里面有一个全局配置crossDomain:false,于是我在ajax请求是加上crossDomain:true,就OK了..让其请求是跨域请求. postdata:function(t,i){ var

解决浏览器跨域限制发送ajax请求

一.什么是浏览器跨域限制?本质是什么? 所谓浏览器跨域限制,其实是为了数据安全的考虑由Netscape提出来限制浏览器跨域访问数据的策略,这是一中约定,正式叫法为浏览器同源策略,目前已经在大多数浏览器中支持. 本质上,所谓浏览器同源策略即:不允许浏览器访问跨域的Cookie,ajax请求跨域接口等.也就是说,凡是访问与自己不在相同域的数据或接口时,浏览器都是不允许的. 最常见的例子:对于前后端完全分离的Web项目,前端页面通过rest接口访问数据时,会出现如下问题: 不允许发送POST请求:在发

axios,vue-echarts, async, vue 图表数据处理; axios 跨域代理; 异步同步请求接口;生命周期函数

1.vue-echarts 安装和组件引用 插件官网 https://github.com/ecomfe/vue-echarts 安装 npm install eacharts vue-echarts 页面引入 import ECharts from 'vue-echarts' import ECharts from 'vue-echarts' import 'echarts/lib/chart/line' // 折线图 import "echarts/lib/component/title&q