你应该知道如何跨域

2023-11-17

前言

转眼就是秋招季啦。经历了几场笔试面试,屡次被问到关于如何实现跨域。老实说,之前都是纸上谈兵,也没有项目需要跨域,甚至觉得这个东西没什么意义。直到今天项目中遇到了跨域问题,看了不少资料才理解跨域的普遍性和意义。特写此篇文章整理自己所得。

转自个人博客: 关于跨域

什么是跨域

一般来说,如果你在开发中需要进行跨域操作(从一个非同源网站发送请求获取数据),一般而言,你在浏览器控制台看到的结果为:

XMLHttpRequest cannot load http://external-domain/service. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://my-domain’ is therefore not allowed access.

同源策略

说到跨域就不得不提“同源策略”。

同源策略是Web浏览器针对恶意的代码所进行的措施,为了防止世界被破坏,为了保护世界的和平,Web浏览器,采取了同源策略,只允许脚本读取和所属文档来源相同的窗口和文档的属性。

那么,怎么判断文档来源是否相同呢?很简单,看三个部分: 协议、主机、端口号。只要其中一个部分不同,则不同源。

跨域的应用场景

  1. 来自 home.example.com 的文档里的脚本读取 developer.example.com载入的文档的属性。
  2. 来自 home.example.com 的文档里的脚本读取 text.segmentfault.com载入的文档的属性。

如何跨域

设置domain属性

针对上述应用场景的***种情况,可以设置Document对象的domain属性。但是设置时使用的字符串必须具有有效的域前缀或者它本身。

PS: domain值中必须有一个点号。

PS: domain不能由松散的变为紧绷的。

复制

//初始值 "home.example.com"  
document.domain = "example.com"; //OK 
document.domain = "home.example.com"; //NO,不能由松散变紧绷 
document.domain = "example"; //NO,必须有一个点号 
document.domain = "another.com"; //NO, 必须是有效域前缀或其本身  

JSONP

JSONP由两部分组成: 回调函数和数据。

原理:通过动态<script>元素来使用,可以通过src属性指定一个跨域URL。

复制

function handler(data){ 
    console.log(data); 
} 
 
var script = document.createElement("script"); 
script.src = "https://segmentfault.com/json/?callback=handler"; 
document.body.insertBefore(script, document.body.firstChild);  

除此之外,还可以利用jQuery来实现。 

复制

function jsonCallback(json){ 
  console.log(json); 
} 
 
$.ajax({ 
  url: "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-2.json", 
  dataType: "jsonp" 
}); 

 运行结果如下:

某些API(例如Github API)允许你定义一个回调函数,当请求返回时执行该函数。 

复制

function logResults(json){ 
  console.log(json); 
} 
 
$.ajax({ 
  url: "https://api.github.com/users/jeresig", 
  dataType: "jsonp", 
  jsonpCallback: "logResults" 
}); 

 运行结果如下:

优点:

  1. 兼容性强。
  2. 简单易用,能之间访问响应文本,支持浏览器与服务器之间双向通信。

不足:

  1. 只能用GET方法,不能使用POST方法
  2. 无法判断请求是否失败,没有错误处理。

跨域资源共享CORS

需要浏览器和服务器同时支持。

原理:使用"Origin:"请求头和"Access-Control-Allow-Origin"响应头来扩展HTTP。其实就是利用新的HTTP头部来进行浏览器与服务器之间的沟通。

针对前端代码而言,变化的地方在于相对路径需改为绝对路径。 

复制

//以前的方式 
var xhr = new XMLHttpRequest();  
xhr.open("GET", "/test", true);  
xhr.send();  
//CORS方式 
var xhr = new XMLHttpRequest();  
xhr.open("GET", "http://segmentfault.com/test", true);  
xhr.send();   

针对服务器代码而言,需要设置Access-Control-Allow-Origin,显式地列出源或使用通配符来匹配所有源。

优点:

  1. CORS支持所有类型的HTTP请求。
  2. 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据

不足:

  1. 不能发送和接收cookie

更新:服务端可以通过设置Access-Control-Allow-Credentials该字段来表示是否允许发送Cookie。发送ajax请求时,需配置withCredentials属性。(感谢sf小伙伴@lloyd_zhou 指正)

具体可查看 阮一峰大大的博客。

  1. 不能使用setRequestHeader()设置自定义头部
  2. 兼容IE10+

postMessage

postMessge()是HTML5新定义的通信机制。所有主流浏览器都已实现。该API定义在Window对象。

复制

otherWindow.postMessage(message, targetOrigin); 
  • 1.

message: 要传递的消息。

targetOrigin: 指定目标窗口的源。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;

当源匹配时,调用postMessage()方法时,目标窗口的Window对象会触发一个message事件。在进行监听事件时,应先判断origin属性,忽略来自未知源的消息。 

复制

//<http://example.com:8080>上的脚本: 
var popup = window.open(...popup details...); 
popup.postMessage("The user is 'bob' and the password is 'secret'", 
              "https://secure.example.net");   
popup.postMessage("hello there!", "http://example.org"); 
 
function receiveMessage(event) 
{ 
  if (event.origin !== "http://example.org") 
    return; 
  // event.source is popup 
  // event.data is "hi there yourself!  the secret response is: rheeeeet!"【见下面一段代码可知】 
} 
window.addEventListener("message", receiveMessage, false);  

针对上面的脚本进行接受数据的操作: 

复制

/* 
 * popup的脚本,运行在<http://example.org>: 
 */ 
 
//当postMessage后触发的监听事件 
function receiveMessage(event) 
{ 
  //先判断源 
  if (event.origin !== "http://example.com:8080") 
    return; 
 
  // event.source:window.opener 
  // event.data:"hello there!" 
 
  event.source.postMessage("hi there yourself!  the secret response " + 
                           "is: rheeeeet!", 
                           event.origin); 
} 
 
window.addEventListener("message", receiveMessage, false);  

后续

收到了很多小伙伴的建议和指正,不胜感激,我会慢慢丰富这篇文章的内容的。请多多指教~

参考文章

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

你应该知道如何跨域 的相关文章

  • Android Navigation的四大要点你都知道吗?

    在JetPack中有一个组件是Navigation 顾名思义它是一个页面导航组件 相对于其他的第三方导航 不同的是它是专门为Fragment的页面管理所设计的 它对于单个Activity的App来说非常有用 因为以一个Activity为架构
  • Vue 如何使用WebSocket与服务器建立链接 持续保持通信

    WebSocket 浏览器通过JavaScript向服务器发出建立WebSocket链接的请求 链接建立后 客户端和服务器端就可以通过TCP链接直接交互数据 WebSocket链接后可以通过 send 方法来向服务器发送数据 并通过 onn
  • JVM优化之 -Xss -Xms -Xmx -Xmn 参数设置

    JVM优化之 Xss Xms Xmx Xmn 参数设置 XmnXmsXmxXss有什么区别 Xmn Xms Xmx Xss都是JVM对内存的配置参数 我们可以根据不同需要区修改这些参数 以达到运行程序的最好效果 Xms 堆内存的初始大小 默
  • 最新整理Java面试八股文,大厂必备神器

    在看这篇文章之前 我想我们需要先搞明白八股文是什么 明清科举考试的一种文体 也称制义 制艺 时文 八比文 八股文章就四书五经取题 内容必须用古人的语气 绝对不允许自由发挥 而句子的长短 字的繁简 声调高低等也都要相对成文 字数也有限制 八股
  • 详解toLowerCase(判断字符串相等)

    一 toLowerCase 函数简介 toLowerCase 是一个在多个编程语言中都存在的字符串方法 它的作用是将字符串中的所有大写字母转换为对应的小写字母 常用于文本处理 搜索和比较等情况 以确保字符串的一致性和非大小写敏感的操作 二
  • 【go语言】结构体数据填充生成md错误码文件

    这里使用pongo2这个模版引擎库进行md文件渲染 GitHub flosch pongo2 Django syntax like template engine for Go package main import fmt github
  • 短信系统搭建主要因素|网页短信平台开发源码

    短信系统搭建主要因素 网页短信平台开发源码 随着移动互联网的快速发展 短信系统已成为企业和个人进行信息传递的重要工具 建立一个高效可靠的短信系统对于企业来说非常重要 下面我们将介绍一些影响短信系统搭建的主要因素 1 平台选择 在搭建短信系统
  • 2024年华为OD机试真题-靠谱的车-Python-OD统一考试(C卷)

    题目描述 程序员小明打了一辆出租车去上班 出于职业敏感 他注意到这辆出租车的计费表有点问题 总是偏大 出租车司机解释说他不喜欢数字4 所以改装了计费表 任何数字位置遇到数字4就直接跳过 其余功能都正常 比如 1 23再多一块钱就变为25 2
  • 初学者如何快速入门Python(内附详细攻略),一文讲清

    目前python可以说是一门非常火爆的编程语言 应用范围也非常的广泛 工资也挺高 未来发展也极好 Python究竟应该怎么学呢 我自己最初也是从零基础开始学习Python的 给大家分享Python的学习思路和方法 一味的买书看书 看视频 是
  • 2024年华为OD机试真题-分割均衡字符串-Python-OD统一考试(C卷)

    题目描述 均衡串定义 字符串只包含两种字符 且两种字符的个数相同 给定一个均衡字符串 请给出可分割成新的均衡子串的最大个数 约定字符串中只包含大写的 X 和 Y 两种字符 输入描述 均衡串 XXYYXY 字符串的长度 2 10000 给定的
  • 基于节点电价的电网对电动汽车接纳能力评估模型研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据
  • 学Python,一个月从小白到大神?看你怎么学!

    Python是一门超强大而且超受欢迎的编程语言 它被用在各种领域 比如网站开发 数据分析 人工智能和机器学习 学会Python会给你创造很多职业机会 所以绝对是值得一试的 但你有没有过这样的梦想 一个月时间 从Python小白变成Pytho
  • 【无标题】

    大家都知道该赛项的规程和样题向来都是模棱两可 从来不说具体的内容 导致选手在备赛时没有头绪 不知道该怎么训练 到了赛时发现题目和备赛的时候完全不一样 那么本文将以往年信息安全管理与评估赛项经验来解读今年2023年国赛的规程 帮助选手们指明方
  • 2024最强Java面试八股文合集(持续更新)

    今天要谈的主题是关于求职 求职是在每个技术人员的生涯中都要经历多次 对于我们大部分人而言 在进入自己心仪的公司之前少不了准备工作 有一份全面细致 面试题 将帮助我们减少许多麻烦 在跳槽季来临之前 特地做这个系列的文章 一方面帮助自己巩固下基
  • 每日变更的最佳实践

    在优维公司内部 我们采用发布单的方式进行每天的应用变更管理 这里给各位介绍优维的最佳实践 变更是需要多角色合作的 而且他是整体研发流程的一部分 在优维内部 我们坚持每日变更 打通开发环节到最终发布上线的全过程 在保证质量的前提下 尽可能提升
  • 在 Python 中实现 List 抽象

    在 Python 中 创建一个包含多个对象的 list 很常见 例如 对于一组具有相同功能的对象 比如播放声音 希望能够使用类似 my list play 的语法来触发 list 中所有对象的 play 方法 另一个例子是 当希望关闭 li
  • 软件测试/测试开发|给你剖析闭包与装饰器的魔力

    测试管理班是专门面向测试与质量管理人员的一门课程 通过提升从业人员的团队管理 项目管理 绩效管理 沟通管理等方面的能力 使测试管理人员可以更好的带领团队 项目以及公司获得更快的成长 提供 1v1 私教指导 BAT 级别的测试管理大咖量身打造
  • Java进阶之旅第七天

    Java进阶之旅第七天 文章目录 Java进阶之旅第七天 方法引用 介绍 代码展示 结果 方法引用的分类
  • 2023下半年软考「单独划线」合格标准公布

    中国计算机技术职业资格网发布了 关于2023年度下半年计算机软件资格考试单独划线地区合格标准的通告 2023下半年软考单独划线地区合格标准各科目均为42分 01 官方通告 关于2023年度下半年计算机软件资格考试单独划线地区合格标准的通告
  • 网工内推 | 上市公司同程、科达,五险一金,年终奖,最高12k*15薪

    01 同程旅行 招聘岗位 网络工程师 职责描述 1 负责职场 门店网络规划 建设 维护 2 负责网络安全及访问控制 上网行为管理和VPN设备的日常运维 3 负责内部相关网络自动化和系统化建设 4 优化与提升网络运行质量 制定应急预案 人员培

随机推荐

  • 虚拟化技术7小问

    目录 kvm中的虚拟机cpu核心大于1 虚拟机就不能启动 只能设置为1的时候虚拟机才能启动 是什么原因 如何查看虚拟机宿主机的CPU是否支持硬件虚拟化 宿主机支持虚拟化 是不是还要开启相关的设置 虚拟机中再安装的虚拟机是不是只能是单核的虚拟
  • 存储器基础入门

    1 泰瑞达机台 Magnum VU本身作为一个灵活 集合式的测试平台 可以支持所有NAND以及MCP MCP Multiple Chip Package 存储器 MCP是在一个塑料封装外壳内 垂直堆叠大小不同的各类存储器或非存储器芯片 是一
  • Android TabLayout setupWithViewPager()方法绑定Viewpager不显示文字

    setupWithViewPager 做了什么事情 TabLayout tabLayout findViewById R id tabLayout ViewPager viewPager findViewById R id viewPage
  • spring框架---IOC

    spring框架的概述 spring是轻量级的开源的JavaEE框架 解决企业应用的开发复杂性 spring有两个核心 IOC AOP IOC 控制反转 把创建对象的过程交给Spring进行管理 AOP 面向切面 不修改源代码的进行功能增强
  • SpringBoot小知识点(可能有你不知道的)

    SpringBoot复习 基础部分 1 SpringBoot中配置文件使用 配置文件间的加载优先级 properties 最高 gt yml gt yaml 最低 2 yaml数据读取 对于yaml文件中的数据 其实你就可以想象成这就是一个
  • 【Salvation】——怪物角色动画&主角碰撞死亡动画

    Salvation 怪物角色动画 主角碰撞死亡动画 写在前面 这个动画功能同样也是使用JavaScript编写脚本 在Unity3D游戏引擎的环境中实现 在怪物的角色动画中 很多与人物相同 这里不再重复 一 设计敌人 拖一个精英sprite
  • Tcp通信步骤

    package cn dali4 code01 TCP通信步骤 服务器先启动 服务器端不会主动请求客户端 必须使用客户端请求服务器 客户端和服务器端建立一个逻辑连接 这个链接包含了一个IO对象 客户端和服务器端可以使用IO对象进行通信 IO
  • 树莓派软连接修改(python为例)

    树莓派软连接修改 进入linux的软连接存放位置 cd usr bin 删除原有软连接 以python为例 rm python 建立新软连接 以python连接python3为例 ln s usr python bin python3 us
  • 大数取模运算,快速幂取模运算

    1 快速幂取模 http www cnblogs com yinger archive 2011 06 08 2075043 html 快速幂取模就是在O logn 内求出a n mod b的值 算法的原理是ab mod c a mod c
  • 微服务系列:Spring Cloud Alibaba 之 Sentinel 高级流控规则

    微服务系列 Spring Cloud Alibaba 之 Sentinel 基本流控规则 在上一篇中 我们学习完了 Sentinel 的基本流控规则 这篇我们来研究一下 Sentinel 的高级流控规则 话不多说 开始今天的学习 一 概述
  • 【进阶项目】Lombok 使用详解

    前言 在 Java 应用程序中存在许多重复相似的 生成之后几乎不对其做更改的代码 但是我们还不得不花费很多精力编写它们来满足 Java 的编译需求比如 在 Java 应用程序开发中 我们几乎要为所有 Bean 的成员变量添加 get set
  • 【java毕业设计】基于java+Lucene+Tomcat的搜索引擎设计与实现(毕业论文+程序源码)——搜索引擎

    基于java Lucene Tomcat的搜索引擎设计与实现 毕业论文 程序源码 大家好 今天给大家介绍基于java Lucene Tomcat的搜索引擎设计与实现 文章末尾附有本毕业设计的论文和源码下载地址哦 需要下载开题报告PPT模板及
  • 忽略shell脚本中回车的方法

    在实际应用过程中 经常遇到需要忽略shell脚本中回车的问题 本文做了一些总结 既有常规操作 也有令人拍案叫绝的方法 且让我慢慢说来 一 使用Linux shell自身的字符串操作 Linux shell内置了一系列的字符串操作符号 可以实
  • 高并发的epoll+多线程

    epoll是linux下高并发服务器的完美方案 因为是基于事件触发的 所以比select快的不只是一个数量级 单线程epoll 触发量可达到15000 但是加上业务后 因为大多数业务都与数据库打交道 所以就会存在阻塞的情况 这个时候就必须用
  • algorithm 修改序列的操作

    文章目录 修正序列算法 fill first last val random shuffle first last partition first last pred rotate first middle last 相关参考 修正序列算法
  • logback历史日志无法自动删除的问题

    例如在logback spring xml进行如下配置
  • 基于Tensorflow实现一个Transformer翻译器

    Transformer是谷歌在2017年的一篇论文 Attention is all you need 提出的一个seq2seq的模型架构 其创造性的提出了自注意力的思想 可以很好的表达序列中各个单词之间的相互注意力关系 这个模型在NLP领
  • html5 canvas+js实现ps钢笔抠图

    html5 canvas js实现ps钢笔抠图 原文 https www cnblogs com guozefeng p 3719915 html 1 项目要求需要用js实现photoshop中钢笔抠图功能 就用了近三四天的时间去解决它 最
  • react antd4.0 渲染树节点

  • 你应该知道如何跨域

    前言 转眼就是秋招季啦 经历了几场笔试面试 屡次被问到关于如何实现跨域 老实说 之前都是纸上谈兵 也没有项目需要跨域 甚至觉得这个东西没什么意义 直到今天项目中遇到了跨域问题 看了不少资料才理解跨域的普遍性和意义 特写此篇文章整理自己所得