前端培训-中级阶段(11、12)- 跨域请求原理以及实现(2019-08-22期)

字节拾贝
• 阅读 2925

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。

JSONP 跨域请求原理以及实现方式jQuery封装的Ajax调用和JSONP数据跨域请求原理和实现

这节题目有点奇怪啊。
上节我们讲了同源策略,这节我们讲讲如何跨域。这东西就和产品提需求一样,我知道不合理,但是我就想要

跨域分类

  1. iframe 跨域
    比如 www.51vv.com 的一部分(header吧),我 k.51vv.com 也想用。默认情况下不同源,是不允许的。那我们怎么办呢?
    前端培训-中级阶段(11、12)- 跨域请求原理以及实现(2019-08-22期)

    1. domain
    2. postMessage
  2. ajax 跨域

    1. JSONP
    2. CORS
    3. 服务器代理
  3. canvas 资源跨域

    1. image 跨域
  4. script 资源跨域

    1. Script error.
      为了提升网站的访问速度,我们通常都会将静态资源文件(css, image, javascript)放在CDN。当这些从CDN的JavaScript脚本执行出错,因为违背了同源策略, 为了保证用户信息不被泄露,错误信息不会显示出来,取而代之只会返回一个Script error.。

ajax 跨域方案

这部分知识是我们开发中经常会遇到的。下面我们来介绍一下常见的几种方法。

JSONP 跨域方案

JSONP 优缺点

  1. 优点

    1. 浏览器兼容性强(全支持)
  2. 缺点

    1. 不安全(嵌入异常逻辑代码)
    2. 只能发GET请求

JSONP 原理

下面我们来说一下JSONP的原理,顺便分析一下上面的优缺点。

  1. 首先 script 标签引入的代码,不管跨不跨域都可以执行。常见的就是CDN的资源,我们拿来使用。
  2. 正常的JSON数据为{code: 200, res: [{id:1,state:0},{id:2,state:1}]}
    如果我们 script 标签引入的资源就是带数据的。
    比如console.log({code: 200, res: [{id:1,state:0},{id:2,state:1}]}),这样不就等于拿到了数据?
  3. 服务端拼接callback名称,动态生成返回数据。

从上面的原理看到JSONP就等于用script加载代码。基于<script>所以兼容性超级棒。同样因为基于<script>代码加载回来了就会执行,如果其中有恶意代码很危险。

CORS 跨域方案

CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
是用来处理跨域问题的一个标准方案。分为两种情况,简单请求非简单请求

优缺点

  1. 优点

    1. 一个标准化的方案。
    2. 对于 ajax 请求的方案。支持(get、post、put、delete)等多种请求方式。
    3. 包含多种跨域情况,比如script跨域,image跨域
    4. 安全。因为他拿到的只是单纯的数据,数据具体怎么使用,还是由开发者来控制。
  2. 缺点

    1. 兼容性较弱(IE 低版本的时候还没这个规范,所以不支持)
    2. 非简单请求首次会预检

简单请求与非简单请求的区分

只要同时满足以下两大条件,就属于简单请求。

  1. 请求方法是以下三种方法之一:HEADGETPOST
  2. HTTP的头信息不超出以下几种字段:

    1. Accept
    2. Accept-Language
    3. Content-Language
    4. Last-Event-ID
    5. Content-Type:只限于三个值

      1. application/x-www-form-urlencoded
      2. multipart/form-data
      3. text/plain

凡是不同时满足上面两个条件,就属于非简单请求。

OPTIONS

浏览器对于这两种请求的处理流程是不一样的。

  • 处理流程的区别?

    • 简单请求:一次请求
    • 非简单请求:两次请求,在发送数据之前会先发一次预检(OPTIONS)请求,只有通过后才会正式的发送请求用于数据传输。
  • 预检请求

    • 请求方式(method):OPTIONS
    • 检查服务器是否支持对应的请求。

      • 通过则允许传输数据
      • 不通过则不再发送真正想要发送的消息(body)
    • 如何预检

      • 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则预检不通过
        Access-Control-Request-Method
      • 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则预检不通过
        Access-Control-Request-Headers

服务器代理 跨域方案

跨域的前提还记得吗?如果我们只请求当前域名不就没问题了吗?我问根据一定规则,让服务端帮我们请求

优缺点

  1. 优点

    1. 兼容极好
    2. 方便更换源
  2. 缺点

    1. 流量问题
    2. 需要主要安全问题,防止代理到内部服务器

nginx实现

    server {
        listen       80;
        server_name  proxy.lilnong.top;
        location = /50x.html {
            root   html;
        }
        location /proxy {
            proxy_pass http://8.8.8.8/;
        }
    }

意味着如果请求https://proxy.lilnong.top/proxy/index.html就会被代理到http://8.8.8.8/index.html;
这里有个注意点proxy_pass http://8.8.8.8/;proxy_pass http://8.8.8.8;。前者会过滤掉location的匹配串,后者不会。

总结

ajax 的跨域目前基本依靠 CORS 来解决。
nginx 用于内网也是不错的选择。
jsonp在一些三方应用上表现还不错。

当然,不管哪种方案都需要服务端的配置

微信公众号:前端linong

前端培训-中级阶段(11、12)- 跨域请求原理以及实现(2019-08-22期)

初级阶段文章目录

  1. 前端培训-初级阶段(17) - 数据存储(cookie、session、stroage)
  2. 前端培训-初级阶段(13) - 正则表达式
  3. 前端培训-初级阶段(13) - 类、模块、继承
  4. 前端培训-初级阶段(13) - ECMAScript (内置对象、函数)
  5. 前端培训-初级阶段(13) - ECMAScript (语法、变量、值、类型、运算符、语句)
  6. 前端培训-初级阶段(13、18)
  7. 前端培训-初级阶段(9 -12)
  8. 前端培训-初级阶段(5 - 8)
  9. 前端培训-初级阶段(1 - 4)

中级阶段文章目录

  1. 前端培训-中级阶段(2) - 事件(event) 事件冒泡、捕获 - (2019-06-20期)
  2. 前端培训-中级阶段(3) - DOM 文档对象模型(2019-06-27期)
  3. 前端培训-中级阶段(4)- BOM 浏览器对象模型(2019-07-04期)
  4. 前端培训-中级阶段(5)- jQuery的概念与基本使用(2019-07-11期)
  5. 前端培训-中级阶段(6)- jQuery元素节点操作(2019-07-18期)
  6. 前端培训-中级阶段(7)- jQuery的事件绑定链式操作及原理(2019-07-25期)
  7. 前端培训-中级阶段(8)- jQuery元素属性样式操作(2019-08-01期)
  8. 前端培训-中级阶段(9)- 原生Ajax的运行原理与实现(2019-08-08期)
  9. 前端培训-中级阶段(10)- 同源策略(2019-08-15期)

资料

  1. 前端培训目录、前端培训规划、前端培训计划
  2. 浏览器同源策略及跨域的解决方法
  3. Same-origin policy
  4. Script error.全面解析
    之前虽然也知道这个错误。但是没有仔细看过。直到静态资源上CDN,才发现了这个问题。
  5. 跨域资源共享 CORS 详解 - 阮一峰的网络日志
    记得当初是一个上传功能,需要走统一上传服务器发现了CORS和OPTIONS。就是在大佬这里看懂的。
点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
4年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
4年前
List的Select 和Select().tolist()
List<PersondelpnewList<Person{newPerson{Id1,Name"小明1",Age11,Sign0},newPerson{Id2,Name"小明2",Age12,
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
4年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这