CORS 请求未能成功_当遇到跨域开发时, 我们如何处理好前后端配置和请求库封装(koa/axios版)...

97bbb84af1256e68018d834c16f2efbc.png

我们知道很多大型项目都或多或少的采用跨域的模式开发, 以达到服务和资源的解耦和高效利用. 在大前端盛行的今天更为如此, 前端工程师可以通过nodejs或者Nginx轻松搭建起web服务器.这个时候我们只需要请求后端服务器的接口即可实现系统的业务功能开发.这个过程中会涉及到web页面API服务器的跨域访问(由于受到浏览器的同源策略,但是业界已有很多解决方案,接下来会介绍).通过这种开发模式使得我们真正的实现了前后端完全分离.

c83c72e2395bd20bc2cc4ae5257130e3.png

采用这种前后端单独开发部署的模式好处有如下几点: 减少后端服务器的并发/负载压力 前端项目和后端项目完全分离, 一定程度上提高了自动化部署的灵活性, 并且代码更易管理和维护 提高前后端开发团队的工作效率, 各司其职, 出现bug更容易定位问题 在大并发情况下可以同水平扩展前后端服务器,利用多台前端服务器做集群来抗住日均千万级的pv 提高应用容错, 即使是API服务器挂了, 前端页面依然能正常访问 API服务器能同时为多个应用平台提供服务, 大量复用接口,提升效率。(比如说微服务)

虽然好处有很多, 但是为了实现以上的架构模式, 我们首先要解决的就是跨域问题.

浏览器的同源策略

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

如果两个URL的protocol(协议,比如http协议,https协议)、port (端口号,如80)和 host(主机,如http://developer.mozilla.org) 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。也就是说如果不满足以上3个条件中的任意一个,则被视为跨域.

解决跨域问题的几种方式

业界解决浏跨域问题的方案很多, 笔者在这里粗略介绍一下: JSONP实现跨域 通过script标签和url回调来实现跨域, 缺点是只支持get请求 CORS CORS需要浏览器和后端同时支持, 后端设置Access-Control-Allow-Origin 就可以开启 CORS postMessage 可以实现跨文本档、多窗口、跨域消息传递(笔者之前写可插拔式聊天机器人就是采用该方案) websocket websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,也是跨域的一种解决方案 nginx反向代理 document.domain + iframe 比较传统的跨域解决方案

目前作为大规模跨域开发使用最多的模式还是CORS方案,所以笔者接下来将具体介绍采用cors模式搭建前后端跨域访问通用解决方案, 为了方便,笔者后端将采用nodejs+koa, (java/php开发类似), 前端采用axios作为请求库来配合实现完整的cors模式.

跨域开发的后端配置(node/koa版)

要想彻底了解cors的跨域模式, 我们还是要深入实践中来, 笔者将采用nodejskoa中间件来实现cors模式的搭建.这里笔者先简单介绍一下cors:

跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头 来告诉浏览器 让运行在一个域上的Web应用被准许访问来自不同源服务器上指定的资源。

基本场景如下:

398d46df9a74f5f2eeaf873911251aae.png

对于简单的跨域场景,我们只需要设置请求头的Access-Control-Allow-Origin字段即可, 比如设置为*号表示允许任何域名的访问.

5a5b69a516190c41961eb6b4c417b844.png

这里我们使用koa2-cors这个中间件来实现一下, 代码如下:

import 

通过这样的配置, 我们就能轻松实现cors跨域, 不过现实开发中我们一般不会这么设置, 因为这样设置意味着任何人都能访问我们的服务,安全性无法保证. 作为小型的开放服务,可以采用这样的配置加上访问限流来实现免费图床类应用.(开放图床实现可以参考笔者之前写的文章

徐小夕:如何使用nodeJs开发自己的图床应用?​zhuanlan.zhihu.com
5cb8fc79bfa4a155ba8851621d9c014f.png

)

在实际开发中, 我们会将origin的返回值设置为指定域名, 这样就只允许该域名下的请求访问, 所以正确的姿势如下:

import 

通过这种方式, 我们在开发环境中, 可以让前端同事自由访问我们的API接口, 提高联调效率, 而在生产环境中只允许我们的WEB服务器所在域名访问.

更进一步

对于简单请求和简单的开发模式, 以上的设计就基本满足要求了, 但是对于复杂的业务场景, 我们的请求模式往往会涉及到更多的要求, 比如说需要携带cookie, 用户凭证或者自定义的请求头信息等(比如典型的JWT认证的token一般会存放到自定义的头信息中), 此时往往会发送预检请求(要求必须先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响).

03055b677dae1dda71d1b2b5378a40b9.png

这里我们需要了解以下几个响应头部的字段: Access-Control-Allow-Methods 表明服务器允许客户端使用的请求方法 Access-Control-Allow-Headers 表明服务器允许请求中携带的头部字段 Access-Control-Max-Age 表明响应的有效时间。在有效时间内,浏览器无须为同一请求再次发起预检请求 Access-Control-Expose-Headers 服务器允许浏览器访问的头信息白名单 * Access-Control-Allow-Credentials 指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容

以上这5个响应头部字段非常重要,这也是我们解决复杂跨域场景的关键配置. 具体配置案例如下:

// 设置跨域

以上是采用koa2-cors实现的方案, 通过设置exposeHeaders, 我们就可以在浏览器端拿到服务器响应的头部字段'WWW-Authenticate', 'Server-Authorization', 'x-show-msg', 进而根据这些字段的值来实现定制化的消息机制.

需要注意的是, 我们服务器在设置credentials后,需要前端请求库配置设置,比如我们需要在axios中设置withCredentials为true, 代码如下:

import 

这样我们就能成功携带用户凭证并被跨域的后端服务器获取了.以上就实现了我们cors模式的后端配置, 对于nodeJS为主的后端选手, 基本任务已经完成, 对于java/PHP选手, 也可以参考类似的配置和库来实现. 接下来我们来实现前端请求库的封装.

跨域开发的前端请求库封装(axios版)

作为一名前端工程师, 没有一个上手的请求库是万万不行的, 目前业界比较好的轮子有axios, umi-request等, 但是后者在使用过程中有一些坑(毕竟基于fetch实现), 所以这里笔者将基于axios来简单实现一个跨域请求库的封装.方便大家集成在自己的vue或者react项目中. 接下来看看请求库封装的简单模型:

718dddba0f9a4ac659abc99cdcfb5fb0.png

笔者将基于http规范的错误类型进行基本的消息系统设计, 代码如下:

import 

以上笔者结合antd的message作为消息反馈UI,利用axios的请求和响应拦截来实现消息系统的设计, 以上只是基本的框架, 大家可以基于以上设计进行更加自定义的封装.

讲到这里, 大家是不是对跨域下的服务端和前端配置有了更进一步的了解了呢?

最后

如果想学习更多H5游戏, webpacknodegulpcss3javascriptnodeJScanvas数据可视化等前端知识和实战,欢迎在《趣谈前端》专栏学习讨论,共同探索前端的边界。

更多推荐

徐小夕:如何用vue/react搭建我们的前端全栈CMS项目​zhuanlan.zhihu.com
f3bddd00e8e4a231cac2c91686379d04.png
徐小夕:基于nodeJS从0到1实现一个CMS全栈项目(中)(含源码)​zhuanlan.zhihu.com
7c039106ef2b4233eb2d09c235e2a553.png
徐小夕:CMS全栈项目之Vue和React篇(下)(含源码)​zhuanlan.zhihu.com
2a697178be7b9e5dcce9065f78440ac0.png
徐小夕:从零到一教你基于vue开发一个组件库​zhuanlan.zhihu.com
1bde2881b89fc22823c58103c06da07c.png
徐小夕:如何从0到1教你搭建前端团队的组件系统​zhuanlan.zhihu.com
0844e028eb54ce5a772677a65001c1d0.png
徐小夕:如何优雅的搭建nodejs开发环境及目录设计?​zhuanlan.zhihu.com
d7207240b9e2f2b132cd33833a57207b.png
徐小夕:彻底掌握redux并开发一个react实战项目​zhuanlan.zhihu.com
b10395616e55aedae07cc9f3b0c31867.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/409998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 数组存入数据库_Java中关于二维数组的理解与使用

今天练习的时候遇到一个题目,题目需求是这样的:需求说明:根据3个班各5名学生某门课程的成绩,正确使用二维数组计算如图所示3个班各自的总成绩分析:要实现这个功能需要存储两个信息:一个是班级信息&#xff…

sql删除元组_Lecture #02: 中级SQL

本专栏是对CMU15445的笔记的翻译,原文地址:https://15445.courses.cs.cmu.edu/fall2020/notes/02-advancedsql.pdf1 关系语言在20世纪70年代,Edgar Codd发布了一篇关于关系模型的论文。最初,他只定义了数据库在关系模型上运行查询…

iCloud官方文档

官方地址:iOS App Programming Guide -> iCloud Storage这个偏理论一些,提供了很多iCloud应用设计层面的东西,大家感兴趣,可以一看。如果需要iCloud上手教程,可以参考我的另外一个贴子:http://www.cocoa…

0x00000000指令引用的内存不能为written_变量和内存访问

计算机世界有一个常识——所有的数据和指令必须经由内存才能进入CPU的寄存器进而被CPU使用,那么我们程序操作的主战场就是内存,内存操作也就顺理成章成为了程序中最高频的操作。为了节目的效果,我们先来看一段8086平台下的汇编代码&#xff1…

Zabbix 3.0 配置企业微信报警(注册---测试)

一、申请企业微信 1、登录企业微信官网,点击企业注册 二、配置企业微信 1、邀请管理员使用企业微信,如果有多个人直接添加新成员 2、管理员收到邀请,下载手机版企业微信,使用微信号登陆即可 3、创建应用 4、填写应用信息&#xff…

AutoMapper 9.0的改造(续)

上一篇有一个读者,有疑问,如何自动化注册Dto 我开篇,做了一个自动化注册的 public sealed class AutoInjectAttribute : Attribute{public Type SourceType { get; }public Type TargetType { get; }public AutoInjectAttribute(Type sourceT…

.net byte转java byte_Java Web安全 || Java基础 Java Agent

点击上方“凌天实验室”,“星标或置顶公众号”漏洞、技术还是其他,我都想第一时间和你分享“【历史】已连载更新全部内容:【菜单栏】-【JAVA SEC】01Java AgentJDK1.5开始,Java新增了Instrumentation(Java Agent API)和JVMTI(JVM …

必须进行支持的游戏方可使用此功能_C#8.0 新增功能

(给DotNet加星标,提升.Net技能)转自:张传宁cnblogs.com/SavionZhang/p/11201818.htmlC#8.0提供了许多增强功能1、Readonly 成员可将 readonly 修饰符应用于结构的任何成员。它指示该成员不会修改状态。这比将 readonly 修饰符应用于 struct 声明更精细。…

Zabbix 3.0 配置企业微信报警(配置zabbix-web)

一、添加报警媒体类型 Name:自定义 Type:选择script Scripts name:填写脚本名称 Script parameters:脚本参数--corpidXXX--corpsecretXXX--user{ALERT.SENDTO}--msg{ALERT.MESSAGE}--agentidXXX最后点Add即可添加完成;…

采用python解决实际问题_Python编程语言解决几种常见的实际问题

Python编程语言解决几种常见的实际问题 (2012-10-25 17:24:12) 标签: it python python培训 北京 杂谈 Python编程语言解决一些实际问题 from os.path import walk, join, normpath from os import chdir, remove def scan(arg, dirname, names) for file in names:…

EevExpress中XtraGrid常用方法

1.girdView在第一列显示行号 调整第一列的宽度 gridView1.IndicatorWidth 40; View Code 1 private void gridView1_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)2 { 3 if (e.Info.IsRowIndi…

【转载】博客园编辑数学公式的方法

原文在这里:博客园编辑数学公式的方法 需要在选项中勾上 启用数学公式支持 在公式开始和结尾输入美元符号 : 如 美元符号x^2美元符号 则显示x的平方 x^2 需要在http://latex.codecogs.com/eqneditor/editor.php里面编辑好后复制源码过来。 如 转载于:htt…

php代码里怎么写html代码_菜鸟青铜变白银!Python 项目代码写完了,然后怎么打包和发布?...

你把你的代码写完了,是不是要给别人使用下,怎么打包你的项目代码呢?喂,开源么?接下来小帅b就跟你说说,如何打包你的代码。就拿我们上次演示的 todo为例,写完代码之后,代码的目录是这…

三次样条插值 cubic spline interpolation

什么是三次样条插值 插值(interpolation)是在已知部分数据节点(knots)的情况下,求解经过这些已知点的曲线, 然后根据得到的曲线进行未知位置点函数值预测的方法(未知点在上述已知点自变量范围内…

vscode python环境_在vscode中配置python环境

原博文 2019-09-27 22:55 − 1.安装vscode和python3.7(安装路径在:E:\Python\Python37); 2.打开vscode,在左下角点击设置图标选择setting,搜索python path,在该路径下选择python的安装路径&…

ufw防火墙规则不生效

正式站系统是Ubuntu 16.04.6 一、今天一个项目有百度爬出,在nginx中封掉还在一直爬取,都403还不停爬取 二、在uwf封掉爬出ip,想封掉80端口没有用,然后封掉整个网段还是没有用,尴尬 三、放出终极大招 UFW(iptables)规则…

network怎么断点调试_Windows 网络编程:调试 API

一次性进群,长期免费索取教程,没有付费教程。教程列表见微信公众号底部菜单进微信群回复公众号:微信群;QQ群:460500587微信公众号:计算机与网络安全ID:Computer-network在Windows中有这么一些AP…

非会员只能试看20分钟_做欧包都要把铁锅烤半小时?太费电了,用我这办法只需预热几分钟...

最近迷上了做欧包,做欧包要用蒸烤箱,做好的欧包才会外脆内软,如果没有蒸烤箱的话人们又研究出了用铸铁锅来做,先把铸铁锅放在烤箱里烘烤半小时左右,然后把面包坯子放入铸铁锅盖好盖子迅速放回烤箱, 因为锅的…