http -- 跨域问题详解(浏览器)

参考链接

参考链接

1.  跨域报错示例

Access to XMLHttpRequest at 'http://127.0.0.1:3000/' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

前端的这个报错相信很多人都有遇到过,也知道这是跨域请求的问题。那到底什么叫跨域呢?

跨域问题简单描述:

       简单一点说,你网页是 xxx.com/xxx.html,这个网页中的元素不允许访问除这个域名以外的其他域名下的资源(也许不严谨,化繁为简能快速理解其本质)。

       再具体一点就是这个页面下的 Ajax 请求,不能去调类似 http://abc.com/xxxx 这样的接口,必须是 xxx.com 下的接口。

2. 了解 什么是域

 :

        域既是 Windows 网络操作系统的逻辑组织单元,也是 Internet 的逻辑组织单元,它是安全边界只有域的所有者才能访问管理域内部的资源,若其他的域要访问或者管理,则需要该域赋予其他域相关权限。

        从小角度来讲,在php中的变量作用域,就可以体现出安全边界的概念。在以下例子中,调用test函数并不会输出任何内容。

<?php
$a = 123;
function test(){
    echo $a;
}
test();

        因为函数内调用的是局部作用域的变量,而在局部作用域内并没有声明 $a 变量。除非我们使用 global $a; 从全局作用域引用该变量。

        在 PHP 脚本中的变量作用域不算复杂,而将一个网站看做一个域,当它要引用其他域的资源时,就需要目标域对原始域进行授权信任。

        这种从其他域获取资源的操作就叫做 跨域

简单理解:

        简单一点,就是域名,http://www.abc.com 下的网页只能调 http://www.abc.com/开头的接口否则就是跨域了,跨域就会报错,上面 2.1 小节那个错误提示。

3. 了解 浏览器的同源策略

同源策略是 Web 的一种安全约定浏览器的同源策略只是对其的一种实现

浏览器同源策略将认为任何站点装载的内容都是不安全的。所以会对跨域的操作或者请求进行限制,从而让用户安全的上网。

同源 指的是 域名、协议、端口 相同。 若有其中一个不同,浏览器将会认为非同源,也就是跨域。

浏览器的同源策略主要有两种

  • DOM 同源策略 : 禁止对不同源页面的 Dom 元素进行操作,主要是在 iframe 标签加载跨域页面出现。
  • XMLHttpRequest 同源策略 : 禁止使用 XHR 对象对不同源地址发起请求。

存储在浏览器中的数据,如 localStroage、Cooke 和 IndexedDB 不能通过脚本跨域访问

3.1 DOM 同源策略

        如果没有 DOM 同源策略,也就是说不同域的 iframe 之间可以相互访问操作。

        那么将会出现这种攻击操作:我们 iframe 包含某个网站的登录页,并且监听目标网站的登录按钮,当用户触发按钮的时候,我们拿到目标网站 input 的dom元素,并且取值,保存到自己的服务器上。

        但是因为有 Dom 同源策略的存在,禁止操作不同源页面的 dom 元素,甚至我们还可以将自己的网站设置 禁止在非同源网站上 iframe ,我们来看看下面的例子

<html>
    <head>
        <title>Siam - Dom同源策略</title>
    </head>
    <body>
        <iframe src="http://www.alipay.com">
    </body>
</html>

运行以上代码,我们会看到支付宝的网站是禁止在了非同源网站上 ifarme。

我们可以看到报错 Refused to display ‘https://www.alipay.com/‘ in a frame because it set ‘X-Frame-Options’ to ‘sameorigin’

X-Frame-Options 是一个HTTP标头(header),用来告诉浏览器这个网页是否可以放在iFrame内。

用法:

X-Frame-Options: DENY     // 不允许iframe
X-Frame-Options: SAMEORIGIN   // 只允许同源的网站iframe
X-Frame-Options: ALLOW-FROM http://yancoo.cn/  // 只允许指定网站iframe

3.2 XMLHttpRequest 同源策略

        如果没有 XHR 同源策略,以及不允许跨域获取 cookies 等的限制,那么攻击者将可以发起 CSRF (跨站请求伪造) 攻击

场景可以如下:

  1. 你登录了某个银行网站,www.siambank.com,银行网站返回你的登录状态并且保存在cookies中。
  2. 你没有安全退出清空cookies,又刚好不小心浏览到了恶意网站 www.ggg.com
  3. 一进入 www.ggg.com ,它将会向 银行网站 发起XHR请求。(发送请求将会带上目标网站设置的cookies)
  4. 银行拿到cookies,验证通过,返回数据。

4. 跨域的解决方法

        前面已经说了,如果想要跨域请求访问或者管理资源,需要目标域赋予权限,到目前为止我们只说了浏览器同源策略的限制,下面我们就再说说赋予权限进行跨域访问相关的知识。

4.1 CORS 跨域资源共享

  CORS 是一个 W3C 标准,该标准定义了在访问跨域资源时,服务端和客户端需要如何沟通,如何授权信任。

CORS的原理是:

        使用 http自定义头部 ,请求头附带客户端信息,服务端验证,并且返回响应头告诉客户端是否允许访问。

        所以该标准需要客户端和服务端同时配合支持,当前所有的浏览器都支持该标准

        CORS 对于用户来说是无感知的,浏览器自动完成 。

        因为当前所有浏览器都支持该标准,并且由浏览器自动完成检测,所以当我们需要使用CORS的时候,只需要由服务端改动,前端不需要改动

        CORS 将 http 请求分为 简单请求 和 非简单请求

        浏览器对于两种类型的请求的处理步骤有一些不同.

      

4.1.1 简单请求 

从名字来理解,就是发送请求的类型或者数据不复杂。

必须同时满足以下两个条件的请求,才是简单请求:

1.  请求方法只能是在以下三种之中。

  • GET
  • POST
  • HEAD

2. HTTP 头部信息不自定义,也就是只能设置默认字段的信息

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type 只限于三个值 application/x-www-form-urlencodedmultipart/form-datatext/plain
  • 等等其他默认字段

简单请求处理步骤:

  1. 浏览器在Http头部带上原始域的标识 Origin
  2. 服务端根据该标识来判断是否需要信任授权,如果信任就在响应头部返回相同的标识。
  3. 浏览器判断响应头是否匹配,做相应结果处理 默认情况下 请求和响应都不带cookies

        如果需要附带cookies信息 ajax的 withCredentials 设置为 true 服务端 响应头需要增加 Access-Control-Allow-Credentials: true

4.1.2 非简单请求

请求方法是简单请求以外,或 http header 包含自定义内容,如:

  • 用到了 PUT、DELETE 等请求方法
  • Content-Type的值是上述三种以外的,如 application\json
  • 用到了自定义 header

非简单请求处理步骤:

  1. 在发送真正请求之前,会先发送一次预检请求,来判断服务端是否支持非简单请求的类方法。
    预检 请求包含跟简单请求一样的 OriginAccess-Control-Request-Method 真实请求的方法 如 PUTAccess-Control-Request-Headers自定义复杂头部(可选)
  2. 预检通过之后,浏览器会再次使用真实请求方法发起请求.
  3. 如果先发送一个方法为 OPTIONS 的预请求 (preflight request) 获得的回应是拒绝性质的,比如404\403\500 等 http 状态,就会停止 post、put 等请求的发出。

预检请求的特点:

  1. 请求信息 
    OPTIONS不会携带请求参数和cookie,也不会对服务器数据产生副作用
    携带 Access-Control-Request-Method 和 Access-Control-Request-Headers
       Access-Control-Request-Method:内容是实际请求的种类,告诉服务器实际请求使用的方法
            Access-Control-Request-Headers:内容是一个以逗号分隔的列表,告诉服务器实际请求复杂请求所使用的头部 
  2. 服务器回传信息    

                Access-Control-Allow-Origin 域,这个是肯定会返回的

      Access-Control-Allow-Methods: 服务器允许客户端使用那些方法发起请求。这个也是肯定会返回的

      Access-Control-Allow-Headers: 当预请求中包含 Access-Control-Request-Headers 时一定会有)这是对预请求当中 Access-Control-Request-Headers 的回复,也是以逗号分隔的列表,可以返回所有支持的头部表明服务器允许请求中携带字段

预见请求如何优化:

        OPTIONS 预检请求的结果可以被缓存!!!

MDN :

        OPTION 返回结果可以被缓存的最长时间(秒)。 在 Firefox 中,上限是 24 小时 (即 86400 秒)。 在 Chromium v76 之前, 上限是 10 分钟(即 600 秒)。 从 Chromium v76 开始,上限是 2 小时(即 7200 秒)。 Chromium 同时规定了一个默认值 5 秒。 如果值为 -1,表示禁用缓存,则每次请求前都需要使用 OPTIONS 预检请求。

4.2 JSONP 跨域解决

在浏览器中,我们可以使用script标签来加载js脚本,如果使用过cdn的童鞋应该知道,我们可以直接填写不同源的地址,因为浏览器允许script加载跨域资源。我们可以通过该标签来加载动态脚本,但是需要服务端调整数据结构

相当于让服务端输出调用js函数的语句

首先我们在html中写下以下代码,创建一个script,调用动态脚本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Siam - script 同源解决</title>
</head>
<body>
    <h1>这是原始页面的内容</h1>
    <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
    <script>
    // 这里需要先写好相应的回调处理函数,然后服务端的脚本调用 传参
    function test(text){
        $('body').append(text);
    }
    $(function(){
        $("body").append("<script src='http://www.siam2.com/script.php'><\/script>");
    })
    </script>
</body>
</html>

服务端脚本:

<?php
echo "test('这是返回内容')";

这样子也可以正常的运行返回.

优点:

  • 兼容性好,现在主流的跨域解决方案之一 缺点
  • 只支持get
  • 要确定 JSONP 请求是否失败并不容易。虽然 HTML5 给 script 标签新增了一个 onerror 事件处理程序,但是存在兼容性问题

4.3  反向代理解决跨域

        除了使用以上的两种方案,我们还可以在nginx 配置反向代理,在www.siam.com下某个路径代理到www.siam2.com即可

我们打开nginx.conf

server {
    listen       80;
    server_name  www.siam.com;
    #charset koi8-r;
    #access_log  logs/host.access.log  main;
    location / {
        root   html;
        index  index.html index.htm;
    }
    location ^~ /apis {
        proxy_pass http://www.siam2.com;
    }
}

        通过反向代理,我们就可以通过 www.siam.com/apis/index2.php 这个路径来访问原来部署在www.siam2.com下的内容。

        这样子就是同源请求了。

5. 跨域访问限制是浏览器安全行为!!!

  1. 误区:
            由于在服务器上做相关匹配就可以允许跨域,所以很多人认为之所以不能跨域访问,是服务器做了相关限制?!这是不对的。
  2. 跨域访问限制是浏览器的行为
           
    阻止你跨域进行 Ajax 请求的是浏览器,不是服务端,并且事实上服务端已经返回了数据到本地,被浏览器拦截下来了,没有呈现到页面上来还抛出了异常。
  3. 如果跨域限制是浏览器行为,为什么是在服务器上做相关配置
            我们可以理解为“服务器授权”,默认情况下浏览器是不允许跨域的,这样可以为各站点数据增加一点安全保护,但如果你的站点在响应请求的时候,带回信息告诉浏览器:“没事,你尽管让他们都来请求好了,我有什么给什么。”,这样一来跨域的限制就解除了。
  4. 为什么App调接口没有跨域的问题?    
           因为跨域的限制是浏览器行为,服务器本身并没有限制访问的源是谁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/259224.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙原生应用再添新丁!喜马拉雅入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;喜马拉雅入局鸿蒙 来自 HarmonyOS 微博12月20日消息&#xff0c; #喜马拉雅正式完成鸿蒙原生应用版本适配#&#xff0c;作为音频业巨头的喜马拉雅 &#xff0c;将基于#HarmonyOS NEXT#创造更丰富、更智慧的全场景“声音宇宙”&#xff01;#鸿…

实验4.2 默认路由和浮动静态路由的配置

实验4.2 默认路由和浮动静态路由的配置 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施1.路由器的基本配置。2.配置默认路由&#xff0c;实现全网互通。3.配置浮动静态路由&#xff0c;实现链路备份。 六、任务验收七、任务小结八、知识链接1&#xff0e;默认路…

【密码学】使用mkcert安装CA、自签名ssl证书,配置nginx的https 证书笔记

文章目录 证书&#xff08;CA证书&#xff0c;服务端证书&#xff0c;客户端证书&#xff09;1 安装CA1.1 下载mkcert1.2 mkcert安装和配置根证书1.3设备安装根证书 2 自签名ssl证书2.1 CA 证书过程:2.2 自签名流程2.3签发证书2.4给已有的证书请求&#xff08;.csr&#xff09;…

嵌入式中串口输入

学习目标 掌握串口初始化流程掌握串口接收逻辑了解中断接收逻辑熟练掌握串口开发流程学习内容 需求 串口接收PC机发送的数据。 串口数据接收 串口初始化 static void USART_config() {uint32_t usartx_tx_rcu = RCU_GPIOA;uint32_t usartx_tx_port = GPIOA;uint32_t usartx…

12.19_黑马数据结构与算法笔记Java

目录 203 排序算法 选择排序 204 排序算法 堆排序 205 排序算法 插入排序 206 排序算法 希尔排序 207 排序算法 归并排序 自顶至下 208 排序算法 归并排序 自下至上 209 排序算法 归并加插入 210 排序算法 单边快排 211 排序算法 双边快排 212 排序算法 快排 随机基准…

QT中网络编程之发送Http协议的Get和Post请求

文章目录 HTTP协议GET请求POST请求QT中对HTTP协议的处理1.QNetworkAccessManager2.QNetworkRequest3.QNetworkReply QT实现GET请求和POST请求Get请求步骤Post请求步骤 测试结果 使用QT的开发产品最终作为一个客户端来使用&#xff0c;很大的一个功能就是要和后端服务器进行交互…

视频号小店怎么做?起店全流程实操分享!

我是电商珠珠 视频号小店距今也不过才发展了一年时间&#xff0c;22年发展的电商平台&#xff0c;经过各种优化到了23年在电商圈激起了不小的火花。 很多想要入驻的新手&#xff0c;在前期并不了解视频号小店怎么做的&#xff0c;不知道开店之后该如何运营。 接下来&#xf…

AutoJS 实现抖音极速版福袋脚本

前言 好久没更新博客了&#xff0c;最近做了个抖音极速版福袋脚本&#xff0c;想看看能不能自动抢到&#xff0c;于是在仿照其他脚本功能做了一个&#xff0c;哈哈。利用上班时间让它自己跑&#xff0c;测试大概2-3天&#xff0c;一个福袋没抢到(也不知道是不是被检测到了)&am…

Linux学习(1)——初识Linux

目录 一、Linux的哲学思想 1.1 基础知识 1.2 根目录下的文件夹 二、Shell 1、Shell的定义 2、Shell的作用 三、Linux命令行 1、Linux通用命令行使用格式 四、Linux命令的分类 1、内部命令和外部命令的理解 2、内部命令和外部命令的区别 3、命令的执行过程 五、编辑…

C语言——内存函数的使用与模拟实现

大家好&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流 本文由&#xff1a;残念ing 原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&#xff0c;欢迎各位…

手把手教你在 windows 上安装 Docker

前言 大家好&#xff0c;我是潇潇雨声&#xff0c;今天为大家带来一篇关于在 Windows 环境下使用 Docker 的教程。对于 Docker&#xff0c;我们可以简单地将其看作一种方便的软件安装方式&#xff0c;而无需深入涉及其复杂的概念。选择使用 Docker 主要是为了省事&#xff0c;比…

【python】在线代码混淆方案及注意事项

▒ 目录 ▒ &#x1f6eb; 导读开发环境 1️⃣ 在线网站pyob混淆操作步骤编写测试代码混淆转pyc缺点中文路径问题&#xff1a;python: Cant reopen .pyc file 2️⃣ 反编译python文件格式对比uncompyle6 3️⃣ 其它方案cpythonpython-obfuscatorPyInstaller【不推荐】pyminifie…

数据结构与算法之美学习笔记:38 | 分治算法:谈一谈大规模计算框架MapReduce中的分治思想

目录 前言如何理解分治算法&#xff1f;分治算法应用举例分析分治思想在海量数据处理中的应用解答开篇内容小结 前言 本节课程思维导图&#xff1a; MapReduce 是 Google 大数据处理的三驾马车之一&#xff0c;另外两个是 GFS&#xff08;hdfs&#xff09; 和 Bigtable(hbase)…

计算机提示vcruntime140.dll丢失的解决方法,多种修复教程分享

vcruntime140.dll是一个非常重要的动态链接库文件&#xff0c;它包含了许多运行时的函数和类。然而&#xff0c;有时候我们可能会遇到vcruntime140.dll无法继续执行代码的问题&#xff0c;这会给我们带来很大的困扰。那么&#xff0c;这个问题是什么原因导致的呢&#xff1f;又…

你知道跨站脚本攻击吗?一篇带你了解什么叫做XSS

1.XSS简介 &#xff08;1&#xff09;XSS简介 XSS作为OWASP TOP 10之一。 XSS中文叫做跨站脚本攻击&#xff08;Cross-site scripting&#xff09;&#xff0c;本名应该缩写为CSS&#xff0c;但是由于CSS&#xff08;Cascading Style Sheets&#xff0c;层叠样式脚本&#x…

华清远见作业第十三天

1.使用多文件编辑&#xff0c; 定义商品信息:商品名称&#xff0c;商品单价&#xff0c;商品购买个数&#xff0c;商品描述&#xff0c;循环输入购买的商品&#xff0c;按单价排序&#xff0c;输出商品信息&#xff0c;计算最贵的商品以及一共花了多少钱? 在create函数&#x…

Python PyCaret:自动化机器学习的利器

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在这篇文章中&#xff0c;将深入介绍 Python 中强大的机器学习库 PyCaret。PyCaret 是一个自动化机器学习工具&#xff0c;旨在简化从数据预处理到模型部署的整个机器学习流程。通过 PyCaret&#xff0c;你可以以…

百度旋转验证码识别(最新)

最近研究了一下图像识别&#xff0c;一直找到很好的应用场景&#xff0c;今天我就发现可以用百度的旋转验证码来做一个实验。没想到效果还挺好&#xff0c;下面就是实际的识别效果。 1、效果演示 2、如何识别 2.1准备数据集 首先需要使用爬虫&#xff0c;对验证码图片进行采…

随时爆雷!2023年四大“安全债”

即将过去的2023年&#xff0c;网络安全、云安全、应用安全、数据安全领域暴露的诸多“安全债”中&#xff0c;有四大债务不但未能充分缓解&#xff0c;反而有在新的一年“爆雷”的风险。这四大债务分别是&#xff1a;Logj4漏洞、HTTP/2快速重置攻击漏洞、恶意电子邮件和后量子加…

《每天一分钟学习C语言·三》

1、 scanf的返回值由后面的参数决定scanf(“%d%d”,& a, &b); 如果a和b都被成功读入&#xff0c;那么scanf的返回值就是2如果只有a被成功读入&#xff0c;返回值为1如果a和b都未被成功读入&#xff0c;返回值为0 如果遇到错误或遇到end of file&#xff0c;返回值为EOF…