前端人员都懂的浏览器的同源策略,以及如何进行不同源间的相互访问

本文涉及的产品
.cn 域名,1个 12个月
简介: 作为前端开发人员,你要是连同源策略都不知道是什么,那就太说不过去了。本篇文章将讲述同源策略的定义, 以及当我们需要克服同源策略,如何进行跨域访问数据的方法。

01

同源策略的定义


同源策略:浏览器自带的一种安全策略,他是指协议域名端口三个都相同的才能互相访问,即若协议、域名、端口有一个不相同时,浏览器禁止页面加载或执行与自身不同域的脚本。


那既然有同源的概念,那必定有不同源的概念,接下来我们来看一个组例子, 理解一下什么是同源,什么是不同源。


url
是否同源(以及原因)
http://www.example.com:80 该 url 与下列的 url 比较
http://www.example.com:80/index.html 同源(协议、域名、端口都相同)
http://www.example.com:5000 不同源(端口不同)
https://www.example.com:80 不同源(协议不同)
http://www.each.com:80 不同源(域名不同)


为什么浏览器会有同源策略?因为如果没有同源策略,别人就可以轻松的获取我们网站的 cookie 信息, 或是对网页进行DOM操作, 要知道这都是非常恐怖的, 尤其是 cookie 信息, 它里面存在着 sessionID ,这是与服务端的 session 会话的重要凭证, 要是被别人得到了 cookie , 可能会造成数据被盗取等后果。


02

同源策略的应用


上面了解了同源策略的定义,但是那还是挺抽象的,那我们接下来来看一下实战中的同源策略是什么样的,借此来更深刻地理解一下同源策略的定义


我们的主体网址是:http://localhost:5000/


(1)请求与自身同域的脚本文件

我们通过jquery的 ajax 来请求 http://localhost:5000/ 下的 data.js 脚本文


    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script><script>      $.ajax({      url: 'http://localhost:5000/data.js',      type: 'get'  })  .done(data => {      console.log(data)  })</script>
    </body></html>


    http://localhost:5000/data.jshttp://localhost:5000/

    是同源的,所以成功请求到了 data.js 脚本文件中的数据, 浏览器也

    没有报错


    (2)请求与自身不同域的脚本文件


    我们通过jquery的 ajax 来请求 http://www.example.com:5000/ 下的 data.js 脚本文件


      <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body>
      <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script><script>      $.ajax({      url: 'http://www.example.com:5000/data.js',      type: 'get'  })  .done(data => {      console.log(data)  })</script>
      </body></html>


      http://www.example:5000/data.jshttp://localhost:500

      0/是不同源的,所以浏览器会报出以下错误:


      6adeda4390e630911cd9b5e3c99b3a91.png


      这个错误大致的意思就是说因为浏览器的同源策略,无法通过该域的网

      去访问别的域下的脚本文件, 这就是浏览器同源策略起到的作用。


      想必大家已经对同源策略有了一定的了解了。那么如果我们有时真的要

      访问别的域下的脚本文件,但因为浏览器存在同源策略,那我们该怎

      么办呢?继续往下看, 看看如何解决这一问题。


      03

      实现不同域的脚本文件访问


      实现不同域的脚本文件访问的方法有很多种,以下举几个例子:


      1. 通过html几个特殊的标签进行访问


      1. 通过jsonp来实现跨域请求


      1. 通过CORS(跨域资源共享)实现跨域请求


      1. 通过代理实现跨域请求(例如nginx 、node中间件)


      (1)通过html几个特殊的标签进行访问


      其实在html里有几个标签存在 src 属性的,例如<script><link> img<iframe>这些标签的 src 属性是不会受到浏览器的同源策略的限制,是可以对不同域下的脚本文件进行访问的。举个例子:

        <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        </body></html>


        我们应该都知道 jquery 可以用外部链接引入吧,这就是通过src 属性,避开了同源策略的限制的一个典型例子。


        (2)通过jsonp来实现跨域请求


        看到 jsonp 就能猜到,这个方法是在需要跨域请求数据时用到的,接下来我们直接来看如何使用。


        • 原生实现jsonp跨域请求


        <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title>
        </head><body>//在script标签的src属性后面,拼接上一个 callback=回调函数名<script src="http://www.example.com:5000/data.js?callback=showDate"></script><script>  //会在跨域请求后,调用该函数    function showDate(data) {        console.log(data)    }</script></body></html>


        • jquery 实现 jsonp跨域请求


        实际上jquery 将jsonp封装在 ajax请求中,原理的话其实就是创建了一个script标签,然后拼接 url 字符串,作为 src 属性的值


          <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body>
          <script src="node_modules/jquery/dist/jquery.min.js"></script><script>    $(function () {        function showDate(data) {            console.log(data)        }        $.ajax({            url: 'http://www.example.com:5000/data.js',            type: 'get',          //请求方式必须为 get            dataType: 'jsonp',    //数据类型改为 jsonp            jsonpCallback: 'showDate'   //数据返回后调用的回调函数        })        .done(data => {            console.log(data)        })    })</script>
          </body></html>


          这样就实现了跟原生一样的通过 jsonp 实现跨域请求的效果。


          (3)通过CORS(跨域资源共享)实现跨域请求

          CORS 这个缩写是不是特别看着特别眼熟?没错,在上面我们做了一个跨域请求报错的实例,图中的报错信息就有这个缩写单词在内, 所以通过CORS(跨域资源共享)也是可以实现跨域请求。因为这个我研究的不太深,我就简单来说一下怎么用吧。


          我们需要向 http://www.example.com:5000/ 请求它下面的 data.js 文件, 我们就只需要服务端给相应头设置一下属性即可,即可完成无论谁跨域请求该域下的 data.js , 都不会因为同源策略而报错, 所以其实这个也有点不太好, 谁都可以访问,那岂不是很危险。


            Access-Control-Allow-Origin:*Access-Control-Allow-Methods:POST,GET,OPTIONSAccess-Control-Allow-Headers:Origin,x-requested-with,content-type,Accept


            这个方法我描述的比较模糊, 因为我也没有深入研究过,所以可能会有点错误,但这确实是一种跨域请求的方法,如果有感兴趣的小伙伴可以去看一下阮一峰老师的一个讲解CORS的日志,直接百度搜索:跨域资源共享CORS详解 - 阮一峰的网络日志


            (4)通过代理实现跨域请求


            我们都知道同源策略是浏览器自带的,那么我们如果要避免同源策略进行跨域请求,我们可以通过代理服务器的方式进行请求,例如我们请求一个与自身不同域的脚本文件,那么我们可以先请求与自身同域的一个 url ,然后通过代理服务器进行跳转, 最后返回由代理服务器请求到的脚本文件,这样说比较抽象,我们用一个node的中间件来举例说一下(其实nginx也可以):


              //引入 express 框架const express = require('express');//引入 代理中间件const { createProxyMiddleware } = require('http-proxy-middleware');//创建服务实例const app = express();
              // 使用一下代理中间件,第一个参数为我们需要代理的 url//                   第二个参数为跳转的 urlapp.use('/api', createProxyMiddleware({ target: 'http://www.example.com:5000', changeOrigin: true }));
              //监听5000端口app.listen(5000);


              按照以上配置完以后, 我们请求http://localhost:5000/api/data.js时, 代理服务器就会自动跳转到 http://www.example.com:5000/data.js , 这样的话我们就完成跨域请求, 并且浏览器也不会报错。


              如果想具体学习一下的小伙伴可以去 github 上看一下这个中间件作者的详细介绍,直接在github搜索:http-proxy-middleware


              其实 nginx也可以完成代理的作用,这里就不多做解释了,如果想要了解的可以去查询一下文档,自行学习一下。


              04

              结束语


              好了,关于同源策略也介绍的差不多了, 有些写的详细,有些写的简略。希望本篇文章对大家能有所帮助。

              相关文章
              |
              1月前
              |
              存储 人工智能 前端开发
              前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
              本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
              128 2
              |
              3月前
              |
              存储 缓存 前端开发
              前端谷歌浏览器面版属性
              【8月更文挑战第19天】前端谷歌浏览器面版属性
              44 0
              |
              12天前
              |
              前端开发 JavaScript API
              前端开发的秘密花园:这些技巧让你轻松应对各种浏览器兼容性问题!
              【10月更文挑战第31天】前端开发是一个充满创意与挑战的领域,追求极致用户体验的同时,浏览器兼容性问题却时常阻碍我们前进。本文将介绍几种解决浏览器兼容性的最佳实践:使用CSS前缀、Autoprefixer工具、现代JavaScript特性与Babel转译、Polyfill与Feature Detection、响应式设计以及跨域问题处理。掌握这些技巧,助你轻松应对各种兼容性难题,创建更稳定、用户友好的网页应用。
              26 3
              |
              11天前
              |
              机器学习/深度学习 自然语言处理 前端开发
              前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
              本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
              |
              12天前
              |
              存储 安全 JavaScript
              浏览器的同源策略
              【10月更文挑战第31天】浏览器的同源策略是浏览器安全模型的重要组成部分,它通过限制不同源之间的资源交互,有效地保护了用户和网站的安全。开发者在进行Web开发时,需要充分理解和遵循同源策略,同时合理地运用各种跨域技术来满足业务需求,确保网站的安全性和功能性的平衡。
              33 2
              |
              20天前
              |
              缓存 前端开发 JavaScript
              "面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
              【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
              54 1
              |
              21天前
              |
              域名解析 网络协议 前端开发
              浏览器输入域名网址访问后的过程详解
              1、以91处理网为例,客户端浏览器通过DNS解析到www.91chuli.com,IP地址是202.108.22.5,通过这个IP地址找到客户端到服务器的路径。客户端浏览器发起一个HTTP会话到202.108.22.5,然后通过TCP进行封装数据包,输入到网络层。
              27 2
              |
              1月前
              |
              机器学习/深度学习 自然语言处理 前端开发
              前端大模型入门:Transformer.js 和 Xenova-引领浏览器端的机器学习变革
              除了调用API接口使用Transformer技术,你是否想过在浏览器中运行大模型?Xenova团队推出的Transformer.js,基于JavaScript,让开发者能在浏览器中本地加载和执行预训练模型,无需依赖服务器。该库利用WebAssembly和WebGPU技术,大幅提升性能,尤其适合隐私保护、离线应用和低延迟交互场景。无论是NLP任务还是实时文本生成,Transformer.js都提供了强大支持,成为构建浏览器AI应用的核心工具。
              426 1
              |
              24天前
              |
              NoSQL 前端开发 MongoDB
              前端的全栈之路Meteor篇(三):运行在浏览器端的NoSQL数据库副本-MiniMongo介绍及其前后端数据实时同步示例
              MiniMongo 是 Meteor 框架中的客户端数据库组件,模拟了 MongoDB 的核心功能,允许前端开发者使用类似 MongoDB 的 API 进行数据操作。通过 Meteor 的数据同步机制,MiniMongo 与服务器端的 MongoDB 实现实时数据同步,确保数据一致性,支持发布/订阅模型和响应式数据源,适用于实时聊天、项目管理和协作工具等应用场景。
              |
              3月前
              |
              机器学习/深度学习 存储 前端开发
              实战揭秘:如何借助TensorFlow.js的强大力量,轻松将高效能的机器学习模型无缝集成到Web浏览器中,从而打造智能化的前端应用并优化用户体验
              【8月更文挑战第31天】将机器学习模型集成到Web应用中,可让用户在浏览器内体验智能化功能。TensorFlow.js作为在客户端浏览器中运行的库,提供了强大支持。本文通过问答形式详细介绍如何使用TensorFlow.js将机器学习模型带入Web浏览器,并通过具体示例代码展示最佳实践。首先,需在HTML文件中引入TensorFlow.js库;接着,可通过加载预训练模型如MobileNet实现图像分类;然后,编写代码处理图像识别并显示结果;此外,还介绍了如何训练自定义模型及优化模型性能的方法,包括模型量化、剪枝和压缩等。
              51 1