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,一经查实,立即删除!

相关文章

大屏某区域滚动效果循环

// 数据自动滚动事件BEGIN var botTimer null; // 定时器对象 $(.tbody).hover(function () { clearInterval(botTimer); // hover}, function () { scrollCore(tbodyScroll, tbody); //out}); //function scrollCore(outerId, innerId) { var winHei $("#" oute…

vue-cli部署ngixs_Vue-cli项目部署到Nginx

项目环境:0. Nginx使用以windows版为例,下载niginx压缩包并解压到任意目录,双击nginx.exe,在浏览器中访问http://localhost,如果出现Welcome to nginx!页面则说明成功。nginx常用命令如下:nginx -h# 打开帮…

2.9.JavaScript--内置对象

<!DOCTYPE HTML><html lang"en-US"><head><meta charset"UTF-8"><title>内置对象</title></head><body><script type"text/javascript">/*var email prompt("请输入电子邮箱地址&q…

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

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

feign接口调用出现连接超时

确认代码无误后,调用出现 connect time out 问题. 因为feign已经集成robbon,hystrix,调用在规定时间内达不到就会报上述错误,并且这个规定时间会很短 解决办法:配置文件加入如下配置: 指的是在调用的一方 #hystrix的超时时间hystrix:command:default:execution:timeout:ena…

mysql截取字符串最后两位_Mysql字符串截取函数SUBSTRING的用法说明

感觉上MySQL的字符串函数截取字符&#xff0c;比用程序截取(如PHP或JAVA)来得强大&#xff0c;所以在这里做一个记录&#xff0c;希望对大家有用。函数&#xff1a;1、从左开始截取字符串left(str, length)说明&#xff1a;left(被截取字段&#xff0c;截取长度)例&#xff1a;…

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

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

算法之快速排序(递归和非递归)

快速排序的两种实现方式.递归和非递归 1 package com.ebiz.sort;2 3 import java.text.SimpleDateFormat;4 import java.util.Arrays;5 import java.util.Date;6 import java.util.Stack;7 8 /**9 * author YHj10 * create 2019-08-18 17:4211 */12 public class Quick {13 …

iCloud官方文档

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

单片机 架构 程序 经验总结_单片机“死机”了怎么办?看看一个资深工程师的经验总结...

原标题&#xff1a;单片机“死机”了怎么办&#xff1f;看看一个资深工程师的经验总结单片机(Microcontroller&#xff0c;MCU) 又称为微控制器或嵌入式控制器&#xff0c;体积虽小&#xff0c;但使用方便&#xff0c;应用范围广泛&#xff0c;在如通讯设备、智能化管理、医疗设…

[html] 使用canvas制作一个印章

[html] 使用canvas制作一个印章 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

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

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

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

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

centos8 挂载ntfs_CentOS 8 挂载NTFS系统磁盘方案

本文最后更新于2020年4月20日&#xff0c;可能会因为没有后期更新而失效。如果您发现本文已经失效或者需要修正&#xff0c;请留言给博主&#xff01;感谢前言Linux 的系统默认是不支持 NTFS 格式的磁盘的&#xff0c;但总有些场景需要插入 USB、移动硬盘等 NTFS 格式磁盘来做文…

AutoMapper 9.0的改造(续)

上一篇有一个读者&#xff0c;有疑问&#xff0c;如何自动化注册Dto 我开篇&#xff0c;做了一个自动化注册的 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

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

ipc$开启telnet

echo offtitle opentelnet cheng...MODE con: COLS44 LINES15:zjmclscolor 0afor /l %%i in (1,1,5) do echo.echo -简介- echo.echo 依靠ipc$来开启Telnet!echo 请按提示输入...echo.set/p ip 输入IP: if /i "%ip%"&…

maven 修改文件名_Maven 构建配置文件

Maven 构建配置文件构建配置文件是一系列的配置项的值&#xff0c;可以用来设置或者覆盖 Maven 构建默认值。使用构建配置文件&#xff0c;你可以为不同的环境&#xff0c;比如说生产环境(Production)和开发(Development)环境&#xff0c;定制构建方式。配置文件在 pom.xml 文件…

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

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