博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网站跨域问题理解及解决方案
阅读量:4146 次
发布时间:2019-05-25

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

文章目录

一、跨域的概念

  • 跨域: 指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制
  • 同源策略: 是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。

在这里插入图片描述

二、options请求

自后天restful接口流行开来,从浏览器请求一个接口会出现调用两次接口的情况(第一次是options请求)。

在这里插入图片描述

为什么发生两次请求

http的请求方式,包括OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT等八种请求方式。其中,get与post只是我们常用的请求方式。

我们从上图看到,第一条的请求方式为options,第二条请求,才是我们预想中的请求。所以为什么发生两条请求的原因就变成了为什么发生options请求。

options请求

官方定义:OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。

用白话说就是:在发生正式的请求之前,先进行一次预检请求。看服务端返回一些信息,浏览器拿到之后,看后台是否允许进行访问。

如何产生options请求

产生options请求的原因包括以下几条:

  • 1、产生了复杂请求。复杂请求对应的就是简单请求。简单请求的定义是:

    • 请求方法是GET、HEAD或者POST,并且当请求方法是POST时,Content-Type必须是application/x-www-form-urlencoded, multipart/form-data或着text/plain中的一个值。
    • 请求中没有自定义HTTP头部。所谓的自定义头部,在实际的项目里,我们经常会遇到需要在header头部加上一些token或者其他的用户信息,用来做用户信息的校验。
  • 2、发生了跨域。

options请求有什么作用

官方将头部带自定义信息的请求方式称为带预检(preflighted)的跨域请求。在实际调用接口之前,会首先发出一个options请求,检测服务端是否支持真实的请求进行跨域的请求。真实请求在options请求中,通过request-header将 Access-Control-Request-Headers与Access-Control-Request-Method发送给后台,另外浏览器会自行加上一个Origin请求地址。服务端在接收到预检请求后,根据资源权限配置,在response-header头部加入access-control-allow-headers(允许跨域请求的请求头)、access-control-allow-methods(允许跨域请求的请求方式)、access-control-allow-origin(允许跨域请求的域)。另外,服务端还可以通过Access-Control-Max-Age来设置一定时间内无须再进行预检请求,直接用之前的预检请求的协商结果即可。浏览器再根据服务端返回的信息,进行决定是否再进行真实的跨域请求。这个过程对于用户来说,也是透明的。

另外在HTTP响应头,凡是浏览器请求中携带了身份信息,而响应头中没有返回Access-Control-Allow-Credentials: true的,浏览器都会忽略此次响应。
总结:只要是带自定义header的跨域请求,在发送真实请求前都会先发送OPTIONS请求,浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。所以复杂请求肯定会两次请求服务端。

三、跨域解决方案

使用nginx部署为同一个域

把前端项目和网关项目, 都放在nginx中,不直接访问前端项目, 而是访问nginx,登录的时候,访问前端项目是静态请求,要到登录后端时候 ,是动态请求, 由nginx反向代理到网关。但此方法只适合于部署的时候,不适合开发环境,处理起来比较麻烦。

在这里插入图片描述

后端服务配置当次请求允许跨域

后端返回响应头, 配置请求跨域的配置, 具体的配置如下图所示

在这里插入图片描述
具体解决方案:在网关中写一个过滤器, 在给前端响应数据之前, 添加跨域的响应头

网关配置跨域

@Configurationpublic class GulimallCorsConfiguration {    @Bean    public CorsWebFilter corsWebFilter(){        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();        CorsConfiguration corsConfiguration = new CorsConfiguration();        //允许跨域的请求头        corsConfiguration.addAllowedHeader("*");        //允许跨域的请求方式        corsConfiguration.addAllowedMethod("*");        //允许跨域的请求来源        corsConfiguration.addAllowedOrigin("*");        //允许携带cookie跨域        corsConfiguration.setAllowCredentials(true);                ///**代表 允许任意的请求路径进行跨域        source.registerCorsConfiguration("/**",corsConfiguration);                return new CorsWebFilter(source);    }}

注意在后端未配置跨域的时候, 请求的响应头是空的。

在这里插入图片描述
重启后端服务后, 再次发生登录的请求。
在这里插入图片描述
完毕!!!

转载地址:http://fonti.baihongyu.com/

你可能感兴趣的文章
Ubuntu系统上安装Nginx服务器的简单方法
查看>>
Ubuntu Linux系统下apt-get命令详解
查看>>
ubuntu 16.04 下重置 MySQL 5.7 的密码(忘记密码)
查看>>
Ubuntu Navicat for MySQL安装以及破解方案
查看>>
HTTPS那些事 用java实现HTTPS工作原理
查看>>
oracle函数trunc的使用
查看>>
MySQL 存储过程或者函数中传参数实现where id in(1,2,3,...)IN条件拼接
查看>>
java反编译
查看>>
Class.forName( )你搞懂了吗?——转
查看>>
jarFile
查看>>
EJB3.0定时发送jms(发布/定阅)方式
查看>>
EJB与JAVA BEAN_J2EE的异步消息机制
查看>>
数学等于号是=那三个横杠是什么符
查看>>
HTTP协议详解
查看>>
java多线程中的join方法详解
查看>>
ECLIPSE远程调试出现如下问题 ECLIPSE中调试代码提示找不到源
查看>>
java abstract修饰符
查看>>
数组分为两部分,使得其和相差最小
查看>>
java抽象类和接口
查看>>
有趣的排序——百度2017春招
查看>>