浏览器跨域问题的总结

2023-10-31

本文主要总结了5中常用的跨域方法,包括JSONP、CORS、Nginx、Proxy与WebSocket。在日常练手的小项目中,推荐CORS,比较方便易理解。(部分图片来源网络,如有侵权,请联系删除)

1:浏览器同源策略:

所谓同源是指:域名、协议、端口相同。核心就在于它认为自任何站点装载的信赖内容是不安全的。浏览器处于安全方面的考虑,只允许本域名下的接口交互, 不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。常用数据传输的方式有ajax与fetch。同源策略又分为以下两种:

  1. DOM 同源策略:禁止对不同源页面 DOM 进行操作。这里主要场景是 iframe (iframe 元素会创建包含另外一个文档的内联框架(即行内框架))跨域的情况,不同域名的 iframe 是限制互相访问的。

  2. XMLHttpRequest 同源策略:禁止使用 XHR 对象向不同源的服务器地址发起 HTTP 请求。

基于同源策略,限制了以下行为:

  • Cookie、LocalStorage 和 IndexDB 无法读取

  • DOM 和 JS 对象无法获取

  • Ajax请求发送不出去

2:跨域的定义与解决方法:

跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。判断是否存在跨域问题很简单,这里就不进行赘述了。主要解决方法如下:

1.JSONP(过老,不常用):

JSONP是一段参数是json格式(大多数情况)的JS代码。Web页面上调用js文件时不受跨域影响(不仅如此,别人还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如script、img、iframe)。工作原理如下:

//客户端
$.ajax({
    url:'http://127.0.0.1:8001/list',
    method:'get',
    dataType:'jsonp',
    success: res=>{
        console.log(res)
    }
});
​
//服务端
let express = require('express'),
    app = express();
app.listen(8001, _ =>{                   // ’_‘ 主要是为了占位
    console.log('ok!')
});
app.get('/list',(req,res) => {
    let {
        callback = Function.prototype  //设置默认值为一个空函数
    } = req.query;
    
    let data = {
        code:0,
        message:'test'
    };
    res.send(`${callback}(${JSON.stringify(data)    // 转义数据, 并发送给回调全局函数中
    })`);
});

优点:不受同源策略的影响 ,兼容性更好,在古老的浏览器中皆可运行,不需要XMLHttpRequest或ActiveX的支持,并且在请求完成后可以通过调用callback的方式回传结果

缺点:只支持GET请求而不支持POST、PUT、DELETE等其他类型的HTTP请求。只支持跨域HTTP请求,不能解决不同域的两个页面之间如何进行JS调用的问题。有可能存在URL劫持问题,返回木马文件,即XSS攻击

2. CORS跨域资源共享(当前流行):

CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。(PS: CORS同时需要后端与浏览器的支持,只要后端实现了CORS,就实现了跨域)

注意:CORS分为简单请求与复杂请求,简单请求需满足以下条件:

1: 使用下列方法之一:GET、HEAD、POST

2:Content -Type的值仅限于下列三者之一: text/plain、multipart/form-data、application/x-www-form-urlencoded

复杂请求:

不符合以上条件的请求就肯定是复杂请求了。 复杂请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求,该请求是 option 方法的,通过该请求来知道服务端是否允许跨域请求。

1:基于Node.js的跨域设置

// 1. 客户端发送ajxa/fetch请求,首先进行axios默认配置
fetch( "http://目标资源网站", {methods:'GET'})
.then(response => response.json())
.then(data => console.log(data))
​
//2:服务器设置相关信息(需要处理options试探性请求--复杂请求)
app.use((req,res,next)=>{
    //允许哪一个源获取数据
    res.header("Access-Control-Allow-Origin","http://loaclhost:8000"); 
    //允许的客户段请求头,可以获取哪些数据
    res.header("Access-Control-Allow-Credentials","Content-Type,Content,Length,Authorization                 , Accept,X-Requested-Width");
    // 允许携带cookie
    res.setHeader('Access-Control-Allow-Credentials', true)
    //运行客户端的请求方式,预检请求,查看客户端是否存在恶意方法methods等来操控数据
    res.header("Access-Control-Alloe-Methods","PUT,POST,GET,DELETE.HEAD.OPTIONS");
    // 预检的存活时间
    res.setHeader('Access-Control-Max-Age', 6)
    // 允许返回的头
    res.setHeader('Access-Control-Expose-Headers', 'name')
​
    if(req.methods==='OPTIONS'){
        res.send('ok!');
        return;
    }
    next();
})

2:基于Python的CORS跨域实现:

def after_request(response):
    # JS前端跨域支持,使用CORS方式
    response.headers['Cache-Control'] = 'no-cache'
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response

更详细的可以看阮一峰大佬的博客:跨域资源共享 CORS 详解 - 阮一峰的网络日志https://www.ruanyifeng.com/blog/2016/04/cors.html

JSONP与CORS的对比:

1: JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。

2: 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

3: JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)

3. Nginx反向代理跨域:

Nginx 实现跨域请和proxy原理一致,只是Nginx帮我们做了服务器转发请求,我们在请求数据时,仍然写自己的网站的请求地址,而不是实际的请求网站的地址。

流程如下:

1:将自己的前端资源部署在Nginx的HTTP服务器

2:设置网站资源根目录

3:在 nginx.conf 配置文件中,设置监听端口与proxy_pass的转发规则

前端通过代理访问数据

server{
    listen          2222;          
    server_name     localhost;      // 设置监听端口为http://localhost:2222
   
    location {
            root   /Users/relax/Desktop/9种跨域/nginx反向代理处理跨域/html;    //# 配置自己的静态网站路径,并指定网站的根目录
            index  index.html index.htm;
    }
    
    location /api{          //转发规则设置,也可使用正则表达式
        proxy_pass   http://127.0.0.1:3000
        add_header   Access-Control-Allow-Origin *;
    }
}

4. http proxy

CORS和JSONP解决跨域问题都有一个前提:需要后台的支持,Proxy可以解决这一问题。一般配合webpack和webpack-dev-server使用,具体流程如下:

  1. 自己的网站端口号是: http://127.0.0.1:12345

  2. 自己网站后台有一个 /proxy 的路由专门处理跨域数据请求.

  3. 同时,有网站提供了一个数据接口,但是端口号是:54321 -> http://127.0.0.1:54321/data.json,因为端口号不同,而产生了跨域问题

  4. 在请求data.json 时,使用/proxy路由进行代理=> http://127.0.0.1:12345/proxy?http://127.0.0.1:54321/data.json

  5. 经自己的服务器解析路径获取到真是的数据连接 http://127.0.0.1:54321/data.json

  6. 自己的服务器由于没有同源策略的限制,所以可以直接发送这个请求,并或者数据返回值.

  7. 最后经由自己的服务器返回给自己的前端浏览器

       VUE中的跨域设置

module.exports = {
    entry: {},
    module: {},
    ...
    devServer: {
        historyApiFallback: true,
        proxy: [{
            context: '/login',
            target: 'http://127.0.0.1:8080',  // 代理跨域目标接口
            changeOrigin: true,
            secure: false,  // 当代理某些https服务报错时用
            cookieDomainRewrite: '127.0.0.1'  // 可以为false,表示不修改
        }],
        noInfo: true
    }
}

5. WebSocket协议跨域

Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 「WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据」。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。

// 客户端
<script>
    let socket = new WebSocket('ws://localhost:3000');
    socket.onopen = function () {
      socket.send('我爱你');//向服务器发送数据
    }
    socket.onmessage = function (e) {
      console.log(e.data);//接收服务器返回的数据
    }
</script>
​
// 服务端
let WebSocket = require('ws'); //记得安装ws
let wss = new WebSocket.Server({port:3000});
wss.on('connection',function(ws) {
  ws.on('message', function (data) {
    console.log(data);
    ws.send('我不爱你')
  });
})

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

浏览器跨域问题的总结 的相关文章

  • 无法让基本的 pjax 示例工作

    编辑 非 工作示例在这里 http www jogos mmorpg com pjax html http www jogos mmorpg com pjax html 我正在尝试重现一个非常基本的 PJAX 示例 如自述文件中所述 htt
  • Spring Security 的 AJAX 请求给出 403 Forbidden

    我有一个基于spring boot spring security thymeleaf的网站 在某些情况下我也使用ajax 问题 我在 Spring Security 中使用表单登录安全性 在浏览器中 登录后我可以使用rest API GE
  • 如果验证失败,如何在 ASP.NET MVC 中阻止 jquery ajax 提交

    我在用ASP NET 5 MVC RC1 我的 ASP NET MVC 使用的 jquery 验证插件是默认 ASP NET 5 模板项目使用的标准 jquery validate js jQuery Validation Plugin v
  • Facebook“赞”按钮回调帮助

    我正在使用此代码进行类似 facebook 的回调 问题是 如果我调用 php 脚本 例如 有人可以看到我的 javascript 并运行此页面 甚至可以向其发送垃圾邮件或在没有先点赞的情况下使用它 我的想法是 我想为每个喜欢该页面的用户提
  • Ajax ModalPopup 在 IE8 - IE9 中显示错误

    我在我的aspx web VB NET 中使用ModalPopup AJAX 使用母版页 它在 ie6 Firefox 中工作正常 但是当我使用IE7 IE8 IE9时 当我想打开Modalpopup时 显示不正确 屏幕被放大 当我使用鼠标
  • 在 WordPress 中挂钩 AJAX

    我一直在深入研究 Javascript 和 AJAX 的世界 我非常接近 但由于某种原因 我认为我没有正确地连接到 wordpress ajax 函数 我已经仔细阅读了文档和这个 认为 99 都在那里 这个应用程序的作用是有一个项目列表 每
  • 如何从 Python 返回 JSON 值?

    我从如下所示的 jQuery 文件发送 ajax 请求 该请求需要 JSON 格式的响应 jQuery ajax url Control getImageDetails file id currentId type GET contentT
  • Rails:通过 Ajax 传递参数

    我需要通过 javascript 将参数传递回服务器 目前 我将它们传递给 JavaScript 如下所示 sendParams 然后像这样将它们发回 function sendParams q ajax url mymodel myact
  • getScript 本地加载而不是全局加载?

    根据我的阅读 JQuery 的 getScript 函数使用名为 global eval 的函数在全局上下文中加载脚本文件 是否有特定的设置或方法可以更改此设置 以便它将改为在我调用它的函数中加载 如果我执行以下代码名称 则返回未定义 因为
  • 如何使用Ext.Ajax登录Spring Security?

    我正在使用 Extjs 6 和 Spring 4 开发一个应用程序 我的应用程序是 Restful 我启用 CORS Origin 如下所示 public class CorsFilter extends OncePerRequestFil
  • 当 ajax 请求验证失败时,如何使用 Primefaces 突出显示 UIInput?

    验证器类 FacesValidator br gov valec sicpd util CpfValidator public class CpfValidator implements Validator Override public
  • iOS 6 上的 Safari 是否缓存 $.ajax 结果?

    自从升级到 iOS 6 以来 我们看到 Safari 的网页视图擅自缓存 ajax来电 这是在 PhoneGap 应用程序的上下文中 因此它使用 Safari WebView 我们的 ajax电话是POST方法并且我们将缓存设置为 fals
  • 使 WebAPI 操作异步?

    我有一个问题 关于在 WebAPI MVC 控制器 AJAX 请求上使用 async await 是否有益 假设我有一个与 Web API 后端对话的 AngularJS 应用程序 并且我想获取一些数据 我对 Web API 进行了一些 A
  • 使用 Express 检测 NodeJS 上的 AJAX 请求

    我正在使用 NodeJS 和 Express 如何区分普通浏览器请求和 AJAX 请求 我知道我可以检查请求标头 但是 Node Exprsss 是否会公开此信息 大多数框架设置了X Requested With标头至XMLHttpRequ
  • 在Java Servlet中获取通过jquery ajax发送的参数[重复]

    这个问题在这里已经有答案了 我在网上搜索这个主题 但找不到有效的示例 我会很高兴有人能给我帮助 这就是我测试的 ajax url GetJson type POST dataType json contentType application
  • Internet Explorer 不渲染从 JQuery ajax 帖子返回的 html

    我有一个带有输入框的页面 其 onkeyup 根据输入的内容 搜索字段 触发 JQuery ajax 帖子 ajax 调用回发的 html 应该填充页面上的另一个 div 这是 jquery ajax 帖子 var o me results
  • 如果 JSF 页面受 j_security_check 保护,则 ajax 请求不会引发 ViewExpiredException

    我有一个不受保护的 JSF 页面j security check 我执行以下步骤 在浏览器中打开 JSF 页面 重新启动服务器 单击 JSF 页面上的命令按钮以发起 ajax 调用 Firebug 表明ViewExpiredExceptio
  • 有没有办法同步ajax调用

    这可能是一个微不足道的问题 但我想知道是否有办法以某种方式知道最后一个 ajax 调用何时完成 假设我有 3 个异步 ajax 调用 ajax type GET datatype json url
  • Django Ajax ModelForm 向 request.POST 提交一个空表单

    对于 django ajax 和 jquery 我是个新手 所以如果我的问题显得微不足道 我提前道歉 我已经在这个问题上摸不着头脑有一段时间了 但我正在尝试使用 ajax 和 jquery 通过 jQuery UI 提供的模式对话框窗口提交
  • HTML5 文件 API 和 AJAX 上传分块问题

    我编写了一个带有单独进度的拖放多个文件上传等 除了一件事之外 它工作得非常好 上传较大文件时 有时浏览器会锁定 直到上传完成 我认为这是因为该文件存储在浏览器的内存中并占用了浏览器可用的所有资源 我想知道 是否可以逐段读取文件并在读取时通过

随机推荐

  • NLP task2 _ 自然语言处理中N-Gram模型的Smoothing算法

    使用N Gram模型时的数据平滑算法 背景 为什么要做平滑处理 零概率问题 就是在计算实例的概率时 如果某个量x 在观察样本库 训练集 中没有出现过 会导致整个实例的概率结果是0 在文本分类的问题中 当一个词语没有在训练样本中出现 该词语调
  • 出圈

    题目描述 设有n个人围坐一圈并按顺时针方向从1到n编号 从第1个人开始进行1到m的报数 报数到第个m人 此人出圈 再从他的下一个人重新开始1到m的报数 如此进行下去直到所剩下一人为止 输入 输入多行 每行2个数 分别表示n和m 输出 计算每
  • AntDesign技术指南:构建优雅的前端界面

    引言 AntDesign是一款优秀的前端UI组件库 它提供了丰富的组件和功能 帮助我们快速构建漂亮 易用的前端界面 本篇博客将详细介绍AntDesign的使用方法和技巧 并展示完整的代码示例 无论你是初学者还是有经验的开发者 本篇博客都将为
  • ISAKMP报文解密

    使用wireshark抓包 No Time Source Destination Protocol Length Info 3 1 735352000 192 168 1 102 192 168 1 101 ISAKMP 878 IKE S
  • react中使用useEffect模拟componentDidUpdata(使 useEffect 在渲染时不执行,只在数据变更时执行)

    背景介绍 在列表搜索条件变化时 需要保存搜索条件 但是保存搜索条件这个方法不需要在组件挂载时执行 即如何使 useEffect 在渲染时不执行 只在数据变更时执行 即模拟类组件的componentDidUpdata 问题描述 如果是使用监听
  • Spring_Accepting request input

    Spring MVC provides several ways that a client can pass data into a controller s handler method These include 1 Query pa
  • Python模块和包

    目录 模块 1 1 导 模块 1 1 1 导 模块的 式 1 1 2 导 式详解 1 2 制作模块 1 2 1 定义模块 1 2 2 测试模块 1 2 3 调 模块 1 2 4 注意事项 1 3 模块定位顺序 1 4 all 包 2 1 制
  • Java项目:二手图书商城平台(java+SSM+JSP+JS+jquery+Mysql)

    源码获取 俺的博客首页 资源 里下载 项目介绍 用户角色包含以下功能 用户登录 查看商品详情 按分类查看 查看我的书架 上传二手书等功能 PS 这个没有管理员角色 环境需要 1 运行环境 最好是java jdk 1 8 我们在这个平台上运行
  • windows安装基于Apache的SVN服务器(包括SSL配置)

    原文地址 http bbs iusesvn com thread 158 1 1 html 参考文章 http blog 163 com shihua 23 blog static 23337594201010564847772 翻译整理
  • idea:父工程的pom.xml中的依赖爆红,下载刷新也没反应

    问题 在创建父工程的时候 使用dependencyManagement管理jar包时 发现有些爆红了 此时的版本号是由 和properties属性来维护的 参考备注掉的红色部分 于是去刷新下载 发现没反应 怎么刷新都不下载jar包 这种问题
  • java8 stream().map().collect()用法

    有一个集合 List
  • Java基础13--面向对象:继承

    Java基础13 面向对象 继承 文章目录 Java基础13 面向对象 继承 继承的概念 生活中的继承 类的继承格式 继承类型 继承的特性 继承关键字 extends关键字 implements关键字 super 与 this 关键字 fi
  • Cesium案列学习(Multi-partCZML.html)

    在学习这个案例之前 先花一点时间了解一下什么是CZML CZML Structure AnalyticalGraphicsInc czml writer Wiki github com Cesium Language CZML 入门1 CZ
  • 中国集成电路产业人才供需报告

    导读 集成电路产业是信息产业的核心 更是支撑经济社会发展和保障国家安全的战略性 基础性和先导性产业 中国大陆集成电路产业处于突破技术封锁 攻坚 卡脖子 瓶颈 构筑核心优势的关键窗口期 迫切需要产业领军人才 专业技术人才 基础研究人才等有力支
  • 什么是静态测试?什么是动态测试?

    如果从被测试对象是否被运行的角度来划分 测试可以分为静态测试和动态测试两种 静态测试是指不运行被测试的软件系统 而是采用其他手段和技术对被测试软件进行检测的一种测试技术 例如 代码走读 文档评审 程序分析等都是静态测试的范畴 常用的静态分析
  • Win10安装Linux子系统WSL(ubuntu2204)及图形桌面xfce4

    WSL简介 什么是 WSL 在计算机上使用 Linux 系统通常有两种方式 使用虚拟机或安装 Linux 系统 使用虚拟机时开销较大 直接使用 Linux 系统虽然可以带来流畅体验 但与 Windows 之间来回切换比较麻烦 为此 微软开发
  • [激光原理与应用-47]:《焊接质量检测》-4-普雷茨特激光焊接过程监控系统LWM分析

    目录 第1章 激光焊接过程监控系统LWM概述 第2章 产品特性与功能 2 1 生产相关的信息 2 2 原始信息检测 2 3 焊接质量分析信息 2 4 缺陷报告与生产控制 2 5 LWM给客户带来的好处 2 6 适用范围 2 7 人机界面 H
  • OCX中主Frame中处理view(备用)

    if m ptmpview NULL m ptmpview GetWindow GW CHILD if m ptmpview NULL m ptmpview gt SendMessage WM PAINT CRect rc CRect 0
  • c++,qt 如何动态获取类的字段的名称和数据

    在C 和Qt中 无法直接通过类来动态获取字段的名称和数据 C 是一种静态类型语言 它在编译时需要确定类的结构 包括字段的名称和数据类型 因此 需要在代码中显式地引用字段名称才能访问其数据 然而 你可以使用反射 reflection 库或自定
  • 浏览器跨域问题的总结

    本文主要总结了5中常用的跨域方法 包括JSONP CORS Nginx Proxy与WebSocket 在日常练手的小项目中 推荐CORS 比较方便易理解 部分图片来源网络 如有侵权 请联系删除 1 浏览器同源策略 所谓同源是指 域名 协议