当前位置:首页 > 技术文章 > 正文内容

前端百题斩之原来跨域也是可以进行分类的

arlanguage4个月前 (12-26)技术文章36

作者: 执鸢者 来源:执鸢者

1同源策略

1.1 同源

跨域本质其实就是指两个地址不同源,不同源的反面不就是同源,同源指的是:如果两个URL的协议、域名和端口号都相同,则就是两个同源的URL。

// 非同源:协议不同 http://www.baidu.com https://www.baidu.com  // 同源:协议、域名、端口号都相同 http://www.baidu.com http://www.baidu.com?query=1

1.2 同源策略

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的加载的脚本如何能与另一个源的资源进行交互。其主要是为了保护用户信息的安全,防止恶意的网站窃取数据,是浏览器在Web页面层面做的安全保护。

1.3 同源策略的表现

既然同源策略是浏览器在Web页面层面做的保护,那么该层面哪些位置需要进行保护呢?总结下来主要包含三个层面:DOM层面、数据层面、网络层面。

DOM层面

同源策略限制了来自不同源的JavaScript脚本对当前DOM对象读和写的操作。

数据层面

同源策略限制了不同源的站点读取当前站点的Cookie、IndexedDB、localStorage等数据。

网络层面

同源策略限制了通过XMHttpRequest等方式将站点的数据发送给不同源的站点。

2 跨域分类

同源策略保证了浏览器的安全,但是如果将这三个层面限制的死死的,则会让程序员的开发工作举步维艰,所以浏览器需要在最严格的同源策略限制下做一些让步,这些让步更多了是在安全性与便捷性的权衡。其实跨域的方式就可以认为是浏览器出让了一些安全性或在遵守浏览器同源策略前提下所采取的一种折中手段。

2.1 DOM层面和数据层面分类

根据同源策略,如果两个页面不同源,无法互相操作DOM、访问数据,但是两个不同源页面之间进行通信是比较常见的情形,典型的例子就是iframe窗口与父窗口之间的通信。随着历史的车轮,实现DOM层面间通信的方式有多种,如下所示:

片段标识符

片段标识符其核心原理就是通过监听url中hash的改变来实现数据的传递,想法真的很巧妙。

// 父页面parentHtml.html <!DOCTYPE html> <html lang="zh">     <head>         <title></title>     </head>     <body>         我是父页面         <button id='btn'>父传给子</button>         <iframe src="./childHtml.html" id="childHtmlId"></iframe>     </body>     <script>         window.onhashchange = function() {             console.log(decodeURIComponent(window.location.hash));         };         document.getElementById('btn').addEventListener('click', () => {             const iframeDom = document.getElementById('childHtmlId');             iframeDom.src += '#父传给子';         });     </script> </html>
// 子页面childHtml.html <!DOCTYPE html> <html lang="zh">     <head>         <title></title>     </head>     <body>         我是子页面         <button id='btn'>子传给父</button>     </body>     <script>         window.onhashchange = function() {             console.log(decodeURIComponent(window.location.hash));         };          document.getElementById('btn').addEventListener('click', () => {             parent.location.href += '#子传给父';         });     </script> </html>

window.name

浏览器窗口有window.name属性,这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它。如果需要实现父页面和跨域的子页面之间的通信,需要一个和父页面同源的子页面作为中介,将跨域的子页面中的信息传递过来。(好麻烦呀,强烈不推荐使用,此处就不写对应的代码啦)

document.domain

document.domain是存放文档的服务器的主机名,可通过手动设置将其设置成当前域名或者上级的域名,当具有相同document.domain的页面就相当于处于同域名的服务器上,如果其域名和端口号相同就可以实现跨域访问数据了。

postMessage(强烈推荐)

window.postMessage是HTML5新增的跨文档通信API,该API,允许跨窗口通信,不论这两个窗口是否同源。

// 父页面 <!DOCTYPE html> <html lang="zh">     <head>         <title></title>     </head>     <body>         我是父页面         <button id='btn'>父传给子</button>         <iframe src="http://127.0.0.1:5500/024/childHtml.html" id="childHtmlId"></iframe>     </body>     <script>         window.addEventListener('message', function(event) {             console.log('父页面接收到信息', event.data);         });         document.getElementById('btn').addEventListener('click', () => {             const iframeDom = document.getElementById('childHtmlId');             iframeDom.contentWindow.postMessage('我是执鸢者1', 'http://127.0.0.1:5500/024/childHtml1.html');         });     </script> </html>
// 子页面 <!DOCTYPE html> <html lang="zh">     <head>         <title></title>     </head>     <body>         我是子页面         <button id='btn'>子传给父</button>     </body>     <script>         window.addEventListener('message', function(event) {             console.log('子页面接收到信息', event.data);         });          document.getElementById('btn').addEventListener('click', () => {             parent.postMessage('我是执鸢者2', 'http://127.0.0.1:5500/024/parentHtml1.html');         });     </script> </html>

2.2 网络层面

根据同源策略,浏览器默认是不允许XMLHttpRequest对象访问非同一站点的资源的,这会大大制约生产力,所以需要破解这种限制,实现跨域访问资源。目前广泛采用的主要有三种方式(注:该出不给出具体代码,后续会有专门的百题斩进行详细阐述):

通过代理实现

同源策略是浏览器为了安全制定的策略,所以服务端不会存在这样的限制,这样我们就可以将请求打到同源的服务器上,然后经由同源服务器代理至最终需要的服务器,从而实现跨域请求的目的。例如可以通过Nginx、Node中间件等。

JSONP的方式(具体实现见后续百题斩)

JSONP是一种借助script元素实现跨域的技术,它并没有使用XMLHttpRequest对象,其能够实现跨域主要得益于script有两个特点:

(1)src属性能够访问任何URL资源,并不会受到同源策略的限制;

(2)如果访问的资源包含JavaScript代码,其会在下载后自动执行。

CORS方式(具体实现见后续百题斩)

跨域资源共享(CORS),该机制可以进行跨域访问控制,从而使跨域数据传输得以安全进行。(实现一个跨域请求的方式,其中html访问网址为http://127.0.0.1:8009; 服务器监听端口为:8010)

(1)html页面内容

<!DOCTYPE html> <html>     <head>         <meta charset="UTF-8">         <title>test CORS</title>     </head>     <body>         CORS         <script src="https://code.bdstatic.com/npm/axios@0.20.0/dist/axios.min.js"></script>         <script>             axios('http://127.0.0.1:8010', {                 method: 'get'             }).then(console.log)         </script>     </body> </html>

(2)服务器端代码

const express = require('express');  const app = express();  app.get('/', (

扫描二维码推送至手机访问。

版权声明:本文由AR编程网发布,如需转载请注明出处。

本文链接:http://www.arlanguage.com/post/493.html

分享给朋友:

“前端百题斩之原来跨域也是可以进行分类的” 的相关文章

Nginx详细介绍

本期我们来说一说nginxNginx介绍nginx是俄罗斯人lgor Sysoev(伊戈尔.塞索耶夫)开发的一款高性能HTTP和反向代理服务器。Nginx以高效的epoll、kqueue、eventport作为网络IO模型,在高并发场景下、Nginx能够轻松支持5W并发连接数的响应,并且消耗的服务器...

Nginx高级篇:从原理到实战,彻底搞懂Nginx

推荐阅读:2020年后想跳槽?MQ、ZK、Nginx、Kafk等分布式技术你都掌握了?手撕分布式技术:限流、通讯、缓存,全部一锅端走送给你惨败阿里,洒泪复习25天,我还能抓住2019的小尾巴上岸网易?微服务架构之春招总结:SpringCloud、Docker、Dubbo与SpringBoot通过配置...

PHP nginx配置 配置nginx支持php

在配置 PHP 和 nginx 以运行 PHP 应用程序时,您需要进行以下步骤:安装 nginx 和 PHP:如果您的系统上尚未安装 nginx 和 PHP,请根据您的操作系统的说明来安装它们。配置 nginx:您需要为 PHP 应用程序创建 nginx 服务器配置。您可以使用以下代码作为模板:ph...

nginx location 多root理解location

由于应用需求,这个 r 目录需要单独拉出来做处理,nginx 最开始是这样写的: server { root /home/webadm/htdocs; index index.php; location /r/ { root /diska/htdocs; } location ~ \.php { f...

容器中Nginx高并发参数调优实战 nginx并发量过高怎么处理

在容器化的微服务架构中,Nginx作为反向代理和负载均衡器,常常需要承担高并发访问的压力。当并发连接数超过Nginx可处理的上限时,就会出现新连接被丢弃的情况。本文将详细介绍如何发现和定位这个问题,并通过调整内核参数和Nginx配置来解决。一、问题现象某Web服务在高并发场景下,偶尔会出现部分请求无...

网站加载慢?让你的网站腾飞起来,LiteSpeed部署

说起LiteSpeed 还得说起我的小站,<开心洋葱网>,虽然流量不大,但是访问是真的慢,无奈经费有限,那就只能在服务器加速上动起心思来。之前一直听说 QUIC 访问网站的速度会让你感觉飞起来,那就搞下吧。我们先来看下 QUIC 、LiteSpeed都是些做什么的?QUIC(Quick...