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

采用这种前后端单独开发部署的模式好处有如下几点: 减少后端服务器的并发/负载压力 前端项目和后端项目完全分离, 一定程度上提高了自动化部署的灵活性, 并且代码更易管理和维护 提高前后端开发团队的工作效率, 各司其职, 出现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应用被准许访问来自不同源服务器上指定的资源。

基本场景如下:

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

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

import 

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

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

)

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

import 

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

更进一步

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

这里我们需要了解以下几个响应头部的字段: 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项目中. 接下来看看请求库封装的简单模型:

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

import 

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

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

最后

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

更多推荐

徐小夕:如何用vue/react搭建我们的前端全栈CMS项目​zhuanlan.zhihu.com

徐小夕:基于nodeJS从0到1实现一个CMS全栈项目(中)(含源码)​zhuanlan.zhihu.com

徐小夕:CMS全栈项目之Vue和React篇(下)(含源码)​zhuanlan.zhihu.com

徐小夕:从零到一教你基于vue开发一个组件库​zhuanlan.zhihu.com

徐小夕:如何从0到1教你搭建前端团队的组件系统​zhuanlan.zhihu.com

徐小夕:如何优雅的搭建nodejs开发环境及目录设计?​zhuanlan.zhihu.com

徐小夕:彻底掌握redux并开发一个react实战项目​zhuanlan.zhihu.com

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

  1. axios 跨域_当遇到跨域开发时,我们如何处理好前后端配置和请求库封装

    我们知道很多大型项目都或多或少的采用跨域的模式开发, 以达到服务和资源的解耦和高效利用. 在大前端盛行的今天更为如此, 前端工程师可以通过nodejs或者Nginx轻松搭建起web服务器.这个时候我们 ...

  2. 已拦截跨源请求:同源策略禁止读取位于...的远程资源。(原因:CORS 请求未能成功)。

    已拦截跨源请求:同源策略禁止读取位于 http://192.168.43.207:8080/manager/login?name=hao&password=111 的远程资源.(原因:CORS ...

  3. Firefox浏览器报错:CORS请求未能成功

    最近在开发中遇到个问题,项目部署完后在Google浏览器能正常使用,但是在Firefox浏览器报跨域拦截(CORS请求未能成功):经检查后端代码以及Nginx都已经配置了跨域相关的代码,按理不应该在出 ...

  4. 【前端44_前后端交互_跨域】前端解决:JSONP、后端解决:CORS 、后端代理

    文章目录 跨域 什么是跨域 前端解决: JSONP 实现原理 步骤 前端:创建标签,拼接传递参数 后端:接收值,返回值 封装 Ajax 代码 在封装的 Ajax 中添加 JSONP 需求 思路 练习: ...

  5. ajax+php跨域请求数据库,基于jQuery的ajax跨域请求,PHP作为服务器端代码

    ajax实现跨域请求有两种方式: 方法一:jsonp的方式 jsonp方式的关键点在客户请求以jsonp作为数据类型,服务器端接收jsonp的回调函数,并通过回调函数进行数据的传输.具体代码如下: 客 ...

  6. 前端跨域请求get_(单点登录)跨域SSO看这篇文章就够了:前端篇

    前言 前俩篇文章,我们从概念,聊到了服务器中设计的内容.不知道大家是否觉得通俗易懂呢? 接下来的内容则有些偏向前端部分. 正文 三.Cookie传递 3.1.通过URL参数实现跨域信息传递 我们要在A ...

  7. Vuejs模拟Ajax请求接口(天气预报API)跨域问题 - 案例篇

    vuejs的Ajax跨域请求问题一直都是前端人员开发vue项目进程中经常遇到的不得不解决的热门问题,也是个心病. 首先看一下,页面 报错内容提示: Access to XMLHttpRequest a ...

  8. 爬取斗图网图片,使用xpath格式来匹配内容,对请求伪装成浏览器, Referer 防跨域请求...

    6.21自我总结 一.爬取斗图网 1.摘要 使用xpath匹配规则查找对应信息文件将请求伪装成浏览器Referer 防跨域请求 2.爬取代码 #导入模块 import requests#爬取网址 ur ...

  9. 测试是否支持跨域_浅谈跨域威胁与安全

    WEB前端中最常见的两种安全风险,XSS与CSRF,XSS,即跨站脚本攻击.CSRF即跨站请求伪造,两者属于跨域安全攻击,对于常见的XSS以及CSRF在此不多谈论,仅谈论一些不太常见的跨域技术以及安全 ...

最新文章

  1. WebService客户端添加SOAPHeader信息
  2. SAP QM 采购订单收货时没有Vendor CoA就不让收货过账的实现
  3. 内存256KB设备也能人脸检测,微软提出用RNN代替CNN | NeurIPS 2020
  4. 基于Python操作ElasticSearch
  5. 《青春飞扬》诗集出版历程与思考分享 之三:游记、感悟与思考
  6. (二)利用Java WebService调用天气预报实践
  7. nodejs命令行执行程序_在NodeJS中编写命令行应用程序
  8. 怎样配oracle环境,oracle配置会话环境(set命令)
  9. 虚拟机服务器被攻击,Linux服务器被攻击用来挖矿了
  10. java web filter 入口_springboot 通过@WebFilter(urlPatterns )配置Filter过滤路径
  11. 最新全国五级行政区划json文件下载链接 全国最新统计用区划代码和城乡划分代码使用指南
  12. oracle期末试题及答案,oracle期末考试试题及答案
  13. 用LM350制作简单可调电源
  14. 计算机网络学习记录——模块一 网络互联基础
  15. 存储系统结构、MDR、MBR、扇区
  16. 吃鸡神器iPhone苹果7Plus手机基础使用教程
  17. 高可用集群下的负载均衡(8):pacemaker + corosync + haproxy 实现高可用
  18. 我的物联网项目(二十七) 分布式锁粗心导致大量阻塞
  19. Python实战案例分享:爬取当当网商品数据
  20. 售价80万!高合汽车,流淌法拉第FF的血液?

热门文章

  1. matlab 16位灰度值转8位,在matlab中如何将灰度值为24位的转化为8?
  2. android模块化 osgi,蚂蚁金融级移动应用 osgi 模块化架构实践.pdf
  3. android native.js,Android Native与JS通信互调
  4. Datatables 给行绑定选中事件
  5. Linux 设备驱动的固件加载
  6. Linux 内核打印级别
  7. java jni ubuntu 环境搭建时遇到的坑
  8. React开发(235):document.body.clientHeight
  9. React开发(134):ant design学习指南之form中getFieldValue
  10. 前端学习(3121):组件和模块