React项目中fetch实现跨域接收传递session的解决方案

本次项目使用了react框架,同时使用fetch取代ajax作为获取接口数据的交互方法。本以为过程中应该不会有什么磕绊,没想到遇到了session丢失这个让人甚是苦恼的问题。期间本想换种方法来对接接口,但转念一想如果每次遇到问题都选择逃避,那么以后的编码之路只能越走越窄,所以还是决定坚持下去。好在经过一整天的摸索,总算是成功攻克了这个难关,下面就对这次问题的解决做个总结。

首先,为什么会出现postman接口调试正常而程序里fetch调用却出现session丢失的问题?

回顾fetch本身的特性——默认情况下, fetch在服务端不会发送或接收任何 cookies!!

再来看session——当客户端第一次请求服务器的时候,服务器生成一份session保存在服务端,将该数据(session)的id以cookie的形式传递给客户端;以后的每次请求,浏览器都会自动的携带cookie来访问服务器(session数据id)。

这就意味着fetch这种方法如果想要携带cookie,需要经过特殊的处理——credentials: "include",代码如下:

fetch("https://ip:端口/api/Values/GetVerifyCode", {

            method: "GET",
            credentials: 'include',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json'
            }
        }).then(res => res.json())
            .then(res => {
                if (res.code == 200) {
                    //xxxxxxx
                }
            });

这里还涉及到前后台分离时经常遇到的跨域问题(mode: 'cors'),什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题。在请求的过程中我们要想回去数据一般都是post/get请求,所以..跨域问题就出现。这是出于浏览器的同源策略限制。(节选自https://zhuanlan.zhihu.com/p/425855609

后台以.netcore webapi为例,需要在Startup.cs里配置好Cors,代码如下:

ConfigureServices里:

services.AddCors(options =>

            {
                options.AddPolicy("any", builder =>
                {
                    builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
                });//跨域请求
            });

Configure里:

app.UseCors("any");//跨域请求

这里要注意的是如果你在服务器端的web.config里已经配置过跨域相关参数了,这里在加的话程序运行时会报错(”*,*”…意思就是重复配置跨域参数),要使用credentials: 'include',需要将上面的允许来自所有域的跨域请求访问改为只允许特定域访问,同时允许Credentials,如下:

services.AddCors(options =>

            {
                options.AddPolicy("any", builder =>
                {
                    builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
                });//跨域请求
            });

本来进行到这里我以为问题已经解决了,在本地调试OK的情况下发布接口,然后调用发布好的服务器接口,却还是没有获取到想要的cookie。以验证码为例:一个fetch1生成验证码,并把它通过响应标头带回来,之后另一个fetch2调接口时把之前带回来的cookie再通过请求标头传到后台进行校验,打开控制台发现fetch2的请求标头并没有cookie值,而fetch1的响应标头里也没有Set-Cookie。

点开末尾的cookie才发现问题的所在:

这个SameSite是何许人也?

SameSite是浏览器请求中Set-Cookie响应头新增的一种属性,它用来标明这个 cookie 是否是“同站 cookie”,同站 cookie 只能在本域名中使用的cookie,不能作为第三方 cookie。Chrome 51 开始,浏览器的 Cookie 新增加了一个SameSite属性,用来防止 CSRF 攻击和用户追踪。该属性起初是由Google 起草的一份草案用来来改进 HTTP 协议的。Chrome 计划将Lax变为默认设置。这时,网站可以选择显式关闭SameSite属性,将其设为None (对旧版浏览器无效,因为旧版浏览器没有该值) 。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。(节选自https://www.cnblogs.com/w821759016/p/14595832.html

了解了这个,便可以很快地对Startup.cs里的services.AddSession做出调整,如下:

services.AddSession(options =>

            {
                options.Cookie.Name = ".AdventureWorks.Session";
                options.IdleTimeout = TimeSpan.FromSeconds(1800);//设置session的过期时间
                options.Cookie.HttpOnly = true;//设置在浏览器不能通过js获得该cookie的值
                options.Cookie.SameSite = SameSiteMode.None;
                options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
                options.Cookie.IsEssential = true;
            });

其中,SameSite设为None配合Secure设为SameAsRequest,但要注意这个只允许访问的接口为https接口,另外将SameSite设置为了Unspecified浏览器则会使用默认值lax,是没有效果的。

最后,将原先的http接口改为https,至于https认证所需的SSL证书怎么搞这里就不赘述了,将这些完成后再次尝试调用发布好的接口,fetch1里的响应标头以及fetch2里的请求标头就都能在控制台看见了,问题解决!

到此这篇关于React项目中fetch实现跨域接收传递session的解决方案的文章就介绍到这了,更多相关react fetch跨域接收传递session内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • React如何解决fetch跨域请求时session失效问题

    前言 fetch在reactjs中等同于 XMLHttpRequest,它提供了许多与XMLHttpRequest相同的功能,但被设计成更具可扩展性和高效性. Fetch 的核心在于对 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用于初始化异步请求的 global fetch.得益于 JavaScript 实现的这些抽象好的 HTTP 模块,其他接口能够很方便的使用这些功能:除此之外,Fetch 还利用到了请求的异步特性--它是基于 Promise

  • react中fetch之cors跨域请求的实现方法

    项目中使用了react,当中需要使用fetch来代替ajax. 由于react的create_react_app工具很方便,基本上开箱即用,经过创建项目,输入npm start命令后,便自动监听一个3000的端口,到此前端部分就绪. 具体参考:https://github.com/facebookincubator/create-react-app 后端部分我使用了phalcon. 由于前后端分离,为了方便,我尝试在nginx中使之同域(前端和后台api的顶级域名相同),但phalcon框架是单

  • React项目中fetch实现跨域接收传递session的解决方案

    本次项目使用了react框架,同时使用fetch取代ajax作为获取接口数据的交互方法.本以为过程中应该不会有什么磕绊,没想到遇到了session丢失这个让人甚是苦恼的问题.期间本想换种方法来对接接口,但转念一想如果每次遇到问题都选择逃避,那么以后的编码之路只能越走越窄,所以还是决定坚持下去.好在经过一整天的摸索,总算是成功攻克了这个难关,下面就对这次问题的解决做个总结. 首先,为什么会出现postman接口调试正常而程序里fetch调用却出现session丢失的问题? 回顾fetch本身的特性

  • 在vue项目中,使用axios跨域处理

    跨域,一个很是让人尴尬的问题,有些人可以在后台中设置请求头,但是很多前端并不具备后台的知识,并无法自己独立的搭建一个服务器,所以就变成了一个尴尬的事情 当然,有很多的虚拟服务器,能够解决跨域问题,他们的实质都是通过后台取与后台沟通,从而委婉的解决跨域问题正好,webpack正有这种功能,所以vue-cli也是有解决跨域的能力 当然,不可能我们直接发送ajax就成功,对吧,我们肯定要修改配置文件 代码: dev: { env: require('./dev.env'), port: 8080, a

  • Vue 项目中遇到的跨域问题及解决方法(后台php)

    问题描述 前端 vue 框架,后台 php,百度跨域问题后台加这段代码 header("Access-Control-Allow-Origin: *"); 加了之后报这个错: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The valu

  • vue项目中常用解决跨域的方法总结(CORS和Proxy)

    目录 一.什么是跨域? 二.如何解决跨域? 总结 一.什么是跨域? 跨域问题的出现是因为浏览器的同源策略问题.所谓同源就是必须有以下三个相同点:协议相同.主机相同.端口相同.如果其中有一项不同,即出现非同源请求,就会产生跨域.当我们请求一个接口的时候,出现如:Access-Control-Allow-Origin 字眼的时候说明请求跨域了 二.如何解决跨域? 跨域的解决方案: jsonpcorsNode中间件代理(两次跨域) 即 Proxynginx反向代理 CORS支持所有类型的HTTP请求,

  • 详解vue-cli项目中的proxyTable跨域问题小结

    什么是跨域? 同源策略规定了如果两个 url 的协议.域名.端口中有任何一个不等,就认定它们跨源了. 跨域的解决方式有哪几种? 1.JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)的简写. JSONP实现跨域请求的原理简单的说,就是动态创建<script>标签,然后利用<script>的src 不受同源策略约束来跨域获取数据. JSONP 由两部分组成:回调函数和数据.回调函数是当响应到来时应该在页面中调用的函数.回调函数的名字一般是在请求

  • 详解如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与React没有任何关系,其他UI框架也可以使用Redux react-redux React插件,作用:方便在React项目中使用Redux react-thunk 中间件,作用:支持异步action 目录结构 Tips:与Redux无关的目录已省略 |--src |-- store Redux目录

  • 优雅的在React项目中使用Redux的方法

    或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与React没有任何关系,其他UI框架也可以使用Redux react-redux React插件,作用:方便在React项目中使用Redux react-thunk 中间件,作用:支持异步action |--src |-- store Redux目录 |-- actions.js |-- index.js |-- reducers.js |-

  • 详解java 中Spring jsonp 跨域请求的实例

    详解java 中Spring jsonp 跨域请求的实例 jsonp介绍 JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题.由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外.利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSO

  • 谈谈如何在ASP.NET Core中实现CORS跨域

    CORS(Cross-origin resource sharing)是一个W3C标准,翻译过来就是 "跨域资源共享",它主要是解决Ajax跨域限制的问题. CORS需要浏览器和服务器支持,现在所有现代浏览器都支持这一特性.注:IE10及以上 只要浏览器支持,其实CORS所有的配置都是在服务端进行的,而前端的操作浏览器会自动完成. 在本例中,将演示如何再ASP.NET Core中实现CORS跨域. 前期准备 你需要windows系统. 你需要安装IIS. 推荐使用VS2015 Upda

  • 在LayUI图片上传中,解决由跨域问题引起的请求接口错误的方法

    在LayUI图片上传中,解决由跨域问题引起的请求接口错误的方法 在ssm框架整合中,使用layui作为前端页面,拖拽图片上传,填写接口后,后台能够成功接收到数据,但由于页面资源和后台访问地址的不一致(即使域名一致但端口不一致)引起跨域问题,导致接收资源后在前端无法接收到后台返回的数据. 前台页面: <html> <head> <meta charset="UTF-8"> <title>校园网络打印</title> <li

随机推荐