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

问题背景
浏览器从一个域名的网页去请求另外一个域名的资源时,域名、端口、协议任一不一样,都是跨域
在先后端开发过程常常会遇到跨域问题。网上也都有解决方案。html


写这篇文章时,咱们碰到的一个场景是:要给s系统作一个扩展,前端的html、js放在s系统里,后端须要作一个单独的站点N.B.com。这就致使了跨域问题,大多数时候 先后端用一个CORS方案 解决跨域问题就能够了。可是我此次有点特别。前端


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

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

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


能够这边后端已经作了CORS处理。为什么还出现这种状况呢。
咱们通常在项目里解决跨域问题简单说会采起方案有ios

  1. 使用ajax直接跨域访问

2.使用JsonP。实际使用时,因为JsonP向Server提交URL的长度限制在8000字符,超过了则被浏览器拒绝,所以不采用。git

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

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 发送的请求ajax

// 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请求问题。json

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

  1. 若是跨域的请求是Simple Request(简单请求 ),则不会触发“PreFlight”。Mozilla对于简单请求的要求是:

如下三项必须都成立:

  1. 只能是Get、Head、Post方法
  2. 除了浏览器本身在Http头上加的信息(如Connection、User-Agent),开发者只能加这几个:Accept、Accept-Language、Content-Type、。。。。
  3. 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'
)

前端这边若是用的vue全家桶 能够这样搞一下

clipboard0.png

module.exports = {
    NODE_ENV: '"development"',
    ENV_CONFIG: '"dev"',
    BASE_API: '"/proxy"'
}

clipboard1.png

'/proxy': {
        target: 'http://jupiter.dev.grdoc.org/',
        changeOrigin: true,
        pathRewrite: {
          '^/proxy': '/'
        },
        sesure:false
      }

开发环境这样搞一下 应该就不算跨域了。


我是山豆 个人gitHub

相关文章
相关标签/搜索