`

[转]理解Flash Player 10.1和AIR 2中的安全更改

 
阅读更多

http://www.infoq.com/cn/vendorcontent/show.action?vcr=1170

 

要求

用户级别

中级

注:本文仅针对开发人员。在 Adobe Flash Player 装机方面有疑问的客户应在 Flash Player 支持中心 上进行检修。

Adobe Flash Player 10.1 和 Adobe AIR 2 提供多种新功能和增强功能,以及部分之前操作的更改。部分更改可能偶尔要求对已有内容进行更新,以符合更加严格的安全规则的要求。其他更改引入了在之前不可用或者受到安全规则限制的新能力。

请阅读下列关于 Flash Player 10.1 和 AIR 2 中与安全相关的更改。使用此列表确定您是否需要对已有内容进行更改,以使其可以在该 Flash Runtime 版本中正常工作。

可能需要行动的更改

该部分描述了需要您更新已有内容的更改。Adobe 非常谨慎地将对已有内容的干扰降到了最低限度,我们相信本文中提到的所有问题将仅对已有内容的一小部分造成影响。

重定向的 URL 截断

在部分情况下,加载 SWF、图像或声音文件后,ActionScript 可能无法看到加载文件的完整 URL。

这种限制影响 ActionScript 3 属性 LoaderInfo.url 和 Sound.url,以及 ActionScript 1 / ActionScript 2 属性 MovieClip._url。当无法显示完整的 URL 时,这些属性将仅显示 URL 的域名部分;如,http://www.example.com/path/my.swf 将被截断为 http://www.example.com/。ActionScript 3 代码可以通过引用名为 LoaderInfo.isURLInaccessible 和 Sound.isURLInaccessible 的新 Boolean 属性检测到截断。在 AS1/AS2 中无 API 可以显示截断。

仅当全部满足下列三个条件时 URL 才被截断:加载文件时发生 HTTP 重定向,文件与调用程序来自不同的域,以及调用程序无可以访问加载文件的许可。

访问加载文件(和其完整 URL)的许可取决于文件类型并使用已有许可机制。访问 SWF 文件的许可在加载 SWF 文件调用 Security.allowDomain(ActionScript 3)或 System.security.allowDomain(ActionScript 1 / ActionScript 2)时被批准。访问图像和声音文件的许可在文件的服务器包含一个策略文件许可访问时被批准。需要访问完整图像或声音 URL 的 ActionScript 3 调用程序需要确保通过将 LoaderContext.checkPolicyFile 或 SoundLoaderContext.checkPolicyFile 设置为“真”预加载策略文件。

什么受影响?

该更改可能会影响任何引用 LoaderInfo.url、Sound.url 或 MovieClip._url 属性的 SWF 文件。该更改影响所有在 Flash Player 10.1 或之后版本中显示的 SWF 文件。该更改影响所有 Adobe AIR 2 或之后版本中的非应用程序内容(但是,AIR 应用程序内容不受影响)。

我需要做什么?

开发人员需要使用 Flash Player 10.1 测试其内容。如果 URL 截断有负效应,开发人员将需要使用 allowDomain 或上面描述的策略文件机制,更新其 SWF 内容以支持截断 URL,或者获得访问加载文件的许可。

剪贴板清除 UIA

在 Flash Player 中,响应用户发起的行动(鼠标点击,键盘输入等)时,SWF 文件可能会仅清除系统 Clipboard。这种限制影响 ActionScript 3 方法 Clipboard.generalClipboard.clear() 和 Clipboard.generalClipboard.clearData()。

此更改反映了这样一个事实:清除 Clipboard 是写入 Clipboard 的一种形式。对于几个版本来说,写入 Clipboard 需要 UIA,如 本开发人员文章 中所述。

什么受影响?

该更改可能会影响任何调用 Clipboard.generalClipboard.clear() 或 Clipboard.generalClipboard.clearData() 方法的 SWF 文件。该更改影响所有在 Flash Player 10.1 或之后版本中显示的 SWF 文件。该更改影响所有 Adobe AIR 2 或之后版本中的非应用程序内容(但是,AIR 应用程序内容不受影响)。

我需要做什么?

开发人员需要使用 Flash Player 10.1 测试其内容。如果 UIA 要求有负效应,开发人员将需要更新其内容,以仅在响应用户输入事件时清除 Clipboard。

for-in 和 for-each 佚代顺序

当 ActionScript 3 代码使用一个 for-in 或 for-each 循环程序在 Object 的属性之间进行佚代时,访问属性的顺序可能偶尔与之前 Flash Player 版本的顺序不同。

想象两种不同类型的 Object 属性名称:简单的和复杂的。大多数情况下,简单属性名称是整数,而复杂属性名称是字符串。但是,也有可能使用任何值作为属性名称——因此,出于完整性目的考虑,Boolean、空和不确定值是简单的属性名称;所有其他类型,包括对象和非整数数值,是复杂属性名称。例如:

var obj : Object = new Object(); 
obj[0] = "a"; // 简单属性名称(整数) 
obj["one"] = "b"; // 复杂属性名称(字符串) 
obj.two = "c"; // 复杂属性名称(字符串)

仅在 Object 有两种类型的属性(简单和复杂)时,for-in 和 for-each 顺序将发生更改。上述示例中的 Object 有两种类型的属性,因此其 for-in 和 for-each 顺序在该 Flash Player 版本中将发生更改。特定更改是首先将访问所有简单属性名称,然后访问所有复杂属性名称。

根据 ActionScript 3 语言参考 中所述,for-in 和 for-each 佚代顺序未定,因此,希望大部分 ActionScript 3 代码不依据未发生更改的佚代顺序。

什么受影响?

该更改可能会影响任何使用 for-in 或 for-each 循环程序的 ActionScript 3 SWF 文件。该更改影响所有在 Flash Player 10.1 或之后版本中显示的 SWF 文件。该更改影响所有 Adobe AIR 2 或之后版本中的内容(既包括应用程序内容也包括非应用程序内容)。

我需要做什么?

开发人员需要使用 Flash Player 10.1 或 AIR 2 测试其内容。如果 for-in 或 for-each 佚代顺序有负效应,开发人员将需要更新其内容,以独立于佚代顺序运行。

与安全相关的可用新功能

该部分介绍新功能。除非您需要使用新功能,负责无须任何行动。

装载环境,循序代码进入

在 Flash Player ActionScript 3 API 中,加载 SWF 文件的方法与加载图像文件(JPEG、PNG 和 GIF)的方法相同。部分情况下,可以加载图像并确保不可能加载 SWF 文件。其中一种极其重要的情况是沙盒导入:从另一个可能不受信任的域导入一个图像文件,并将其重新分配到加载程序的安全域中。导入一个不受信任的图像文件通常情况是无害的,因为不受支持的图像文件格式无法包含可执行代码,但是导入一个不受信任 SWF 文件可能会更加危险。

有两种 Flash Player 方法可以执行沙盒导入。两种方法均仅在 ActionScript 3 中可用。第一种方法是 Loader.loadBytes,从 ActionScript 中取得原始二进制数据,并将其作为展示媒体加载。第二种方法是 Loader.load,其中 LoaderContext.securityDomain = SecurityDomain.currentDomain,从 URL 加载媒体。

对于 Flash Player 10.1 和 AIR 2,您可以通过指定 LoaderContext.allowCodeImport = false 限制两种方法仅加载图像。以下是使用 loadBytes 的部分示例代码:

var ld : Loader = new Loader();
ld.contentLoaderInfo.addEventListener("complete", onLoadComplete);
ld.contentLoaderInfo.addEventListener("securityError", onSecurityError);
var lc : LoaderContext = new LoaderContext();
lc.allowCodeImport = false;
ld.loadBytes(myByteArray, lc);

如果当您为导入操作设置 LoaderContext.allowCodeImport = false 时要加载的内容是 SWF 文件,将分派一个 SecurityError 事件,显示错误 3226:

"Cannot import a SWF file when LoaderContext.allowCodeImport is false."

请注意:LoaderContext.allowCodeImport 仅影响执行沙盒导入的情况——因此,例如,一个普通的 Loader.load 操作将总是可以加载 SWF 文件或图像文件,即便 LoaderContext.allowCodeImport = false。

LoaderContext.allowCodeImport 是一个较早的名为 LoaderContext.allowLoadBytesCodeExecution 的仅 AIR 属性的概括。在 AIR 中,两个属性现在是同义词。在 AIR 中,LoaderContext.securityDomain 属性不受支持,因此在 AIR 中执行沙盒导入的唯一方法是 Loader.loadBytes,这就是旧的仅 AIR 属性名为 allowLoadBytesCodeExecution 的原因。新属性名称 LoaderContext.allowCodeImport 是首选,因为它在 Flash Player 同样受支持。

SWF 文件将图像文件导入其自己的沙盒有两个常见原因。首先是 Loader.loadBytes 支持动态图像处理和复制。其次是导入将删除安全限制,如检查像素值或调用 BitmapData.draw。

注:导入图像首先总是需要一个策略文件——因此,这仅仅是一种将安全检测移至较早阶段的方法。

后续工作

关于 Flash Player 安全的最新发展,请访问 安全话题中心。Adobe 为每个 Flash Player 版本都发布了一篇类似本文的文章。

您也可以从 Flash Player 下载中心 下载 Flash Player 10.1

分享到:
评论

相关推荐

    Flash+Flex+Air移动开发入门经典 pdf

    《flash+flex+air移动开发入门经典——适用于android、ios和blackberry》 第1章 flash、flex和air简介 1 1.1 adobe flash 1 1.2 actionscript 3.0 2 1.2.1 ecmascript 2 1.2.2 关键概念 3 1.3 flex框架 11 ...

    thymeleaf-2.0.15.jar中文文档.zip

    # 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

    javassist-3.25.0-GA.jar中文-英文对照文档.zip

    # 压缩文件中包含: 中文-英文对照文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文-英文对照文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

    “计及源荷双重不确定性的虚拟电厂微网日前随机优化调度模型设计与实现(基于蒙特卡洛与概率距离法处理不确定性变量)”

    内容概要:本文详细介绍了利用MATLAB进行虚拟电厂日前随机优化调度的方法。首先,通过蒙特卡洛模拟生成大量光伏出力和负荷的随机场景,考虑到光伏出力和负荷预测的不确定性。接着,采用概率距离削减法将大量场景缩减为少数典型场景,确保计算效率的同时保留重要特征。然后,构建随机优化模型,将燃气轮机、储能、弃光等成本纳入目标函数,并设置严格的功率平衡和设备出力限制作为约束条件。最终,使用CPLEX求解器求解该混合整数规划问题,得到最优调度方案。实验结果显示,相比传统确定性优化,随机优化显著提高了系统的鲁棒性和经济效益。 适合人群:从事电力系统研究、虚拟电厂调度、智能电网优化的研究人员和技术人员。 使用场景及目标:适用于需要处理光伏出力和负荷预测不确定性的虚拟电厂调度场景,旨在提高调度方案的稳定性和经济性,降低运营风险。 其他说明:文中提供了详细的MATLAB代码片段,帮助读者理解和实现具体的算法步骤。此外,还给出了若干实用技巧和注意事项,如场景削减时的概率归一化、储能SOC约束的跨场景耦合等。

    aws-java-sdk-s3-1.12.249.jar中文文档.zip

    # 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

    农产品销售管理系统 - Java课程设计项目 - SpringBoot毕业设计 - Vue+MySQL期末大作业

    农产品销售管理系统基于SpringBoot+MyBatisPlus+Vue+MySQL开发,专为Java课程设计、毕业设计及初学者打造。适合作为Java期末大作业或实战练手项目。采用IDEA开发,技术主流,代码规范,帮助快速掌握全栈开发技能,助力Java学习与答辩!

    aws-java-sdk-s3-1.12.254.jar中文-英文对照文档.zip

    # 压缩文件中包含: 中文-英文对照文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文-英文对照文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

    物联网设备开发_蓝牙低能耗BLE技术_小米手环1非心率版数据读取与控制_实现Android平台下小米手环1代非心率版设备的蓝牙连接_步数数据获取_电量监测_震动控制功能_适用于An.zip

    物联网设备开发_蓝牙低能耗BLE技术_小米手环1非心率版数据读取与控制_实现Android平台下小米手环1代非心率版设备的蓝牙连接_步数数据获取_电量监测_震动控制功能_适用于An

    安卓系统开发_蓝牙低功耗监测与音频控制_支持AirPods全系列电量显示与入耳检测_为OPPO手机深度优化并兼容其他安卓设备的智能耳机管理助手_实现耳机离耳自动暂停和入耳自动播放功.zip

    安卓系统开发_蓝牙低功耗监测与音频控制_支持AirPods全系列电量显示与入耳检测_为OPPO手机深度优化并兼容其他安卓设备的智能耳机管理助手_实现耳机离耳自动暂停和入耳自动播放功

    基于.NET 6的WPF工具:集成OpenCVSharp与ReactiveUI,深度学习目标识别及3D点云数据处理

    内容概要:本文介绍了一个基于.NET 6 WPF框架构建的多功能图像处理与3D点云显示工具。该项目集成了ReactiveUI用于响应式UI设计,OpenCVSharp用于图像处理,以及HelixToolkit用于3D点云渲染。通过ReactiveUI实现了参数的实时调整和图像处理的即时反馈,如Canny边缘检测、高斯模糊等。此外,项目还包括了YOLOv4的目标检测功能,支持多种3D点云格式的导入和渲染。文中详细描述了各个模块的技术实现细节,包括性能优化和常见问题的解决方案。 适合人群:熟悉.NET和WPF框架的开发者,尤其是对图像处理和3D点云感兴趣的研发人员。 使用场景及目标:① 实时调整图像处理参数,快速验证算法效果;② 作为3D点云查看器,支持多种格式的点云数据;③ 集成YOLOv4进行目标检测,适用于计算机视觉领域的研究和开发。 其他说明:项目仍在持续改进中,源码中有许多待优化的地方,提供了丰富的扩展空间和技术挑战。

    人工势场法路径规划Matlab代码详解:涵盖两种方法的编写与注释,公式解释及A*、rrt等算法整合

    内容概要:本文探讨了机器人路径规划领域的多种经典算法,重点介绍了人工势场法的基本原理和Matlab实现方法。文中不仅提供了传统人工势场法的具体代码实现,还针对其易陷入局部最优的问题提出了改进措施,如引入随机扰动。此外,简要提及了A*和RRT算法的特点及其实现思路。通过详细的代码解析和参数调优指南,帮助读者更好地理解和应用这些算法。 适合人群:对机器人路径规划感兴趣的初学者以及有一定编程基础的研究人员。 使用场景及目标:适用于希望深入了解人工势场法的工作原理并掌握其具体实现的技术人员。目标是能够独立编写和优化路径规划算法,特别是在Matlab环境下进行实验和验证。 其他说明:文章附带了完整的代码片段和注释,便于读者实践操作。同时强调了不同算法的选择依据和应用场景,鼓励读者根据实际情况灵活选用合适的方法。

    威纶通触摸屏一机多屏程序

    内容概要:本文深入介绍了威纶通触摸屏一机多屏程序及其与FX3U系列PLC和MODBUS通讯的集成应用。首先,文章阐述了系统的硬件架构,即一个FX3U系列PLC搭配四个MT6051ip触摸屏的工作原理。接着,详细解析了威纶通模板的特点,特别是梯形图的详尽注释,便于理解和维护。此外,文章还探讨了PLC与上位机的MODBUS通讯设置,包括波特率、数据位、停止位等参数的具体配置方法。最后,强调了该系统的学习意义和借鉴价值,适用于新手和资深工程师。 适合人群:从事自动化控制领域的工程师和技术人员,尤其是那些希望深入了解PLC、触摸屏和MODBUS通讯的人群。 使用场景及目标:①帮助工程师快速掌握威纶通触摸屏的一机多屏配置;②提高PLC与触摸屏、上位机之间的通讯效率;③优化中小型企业生产线的监控系统,提升生产效率和稳定性。 其他说明:文中提供的实例和代码片段有助于读者更好地理解和实践相关技术,同时附带了一些实用的小技巧,如心跳检测和双看门狗设计,增强了系统的可靠性和容错能力。

    CNC雕刻机STM32F407源码详解:带详细中文注解与原理图解析

    内容概要:本文深入剖析了一款基于STM32F407的CNC雕刻机控制系统,涵盖硬件原理图和源码实现。首先介绍了步进电机驱动部分,详细解释了XYZ三轴的方向引脚配置及时序控制,确保电机平稳运行。接着讨论了PWM脉冲生成的核心配置,通过定时器精确控制雕刻精度,并解决了高速雕刻时的脉冲丢失问题。串口通信部分采用DMA+空闲中断,显著提升了数据处理效率。运动插补算法利用定时器触发DMA传输脉冲,实现高效的三轴联动。此外,文中还涉及了G代码解析、运动前瞻算法以及硬件设计中的防呆措施,如IO口的TVS二极管和RC滤波。最后,分享了一些调试经验和隐藏的开发彩蛋,如通过LED灯效显示工作状态和电流检测实现堵转保护。 适合人群:具备嵌入式开发基础,尤其是对STM32和CNC雕刻机感兴趣的开发者和技术爱好者。 使用场景及目标:①帮助开发者理解和实现CNC雕刻机的控制系统;②提供详细的硬件和软件设计方案,便于动手制作;③分享调试技巧和实战经验,提高系统的稳定性和可靠性。 阅读建议:本文不仅提供了详细的代码实现和硬件设计,还包括了许多实战经验和调试技巧,因此在阅读过程中应重点关注这些细节,并尝试复现相关功能。

    aws-java-sdk-s3-1.12.242.jar中文-英文对照文档.zip

    # 压缩文件中包含: 中文-英文对照文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文-英文对照文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

    karson711_JKCircleViewDemo_12888_1745868188120.zip

    karson711_JKCircleViewDemo_12888_1745868188120

    医学超声成像_基于FPGA和CYUSB30的超声信号处理_超声波发射与AD采集_剪切波弹性成像_多通道数据同步传输_高速BULK传输_URAT状态控制_4096点扫描线采集_30.zip

    医学超声成像_基于FPGA和CYUSB30的超声信号处理_超声波发射与AD采集_剪切波弹性成像_多通道数据同步传输_高速BULK传输_URAT状态控制_4096点扫描线采集_30

    一些小游戏,比较好玩,windows10系统运行

    一些小游戏,比较好玩,windows10系统运行

    三菱FX3U PLC画圆程序:同心的圆及子程序循环插补法

    内容概要:本文详细介绍了如何利用三菱FX3U PLC通过360等份插补的方法绘制三个同心圆。首先将圆分解为360个等分点,通过三角函数实时计算各点的X/Y坐标,采用子程序循环调用来实现连续运动。文中提供了具体的代码片段,展示了如何通过寄存器配置和三角函数计算来精确控制圆的绘制过程。此外,还讨论了如何通过调整参数实现不同的图形效果,如虚线圆、螺旋线等。并强调了该方法在工业应用中的灵活性和高效性。 适合人群:对PLC编程有一定基础,希望深入了解PLC在工业控制中具体应用的研发人员和技术爱好者。 使用场景及目标:适用于需要进行精密轨迹控制的应用场合,如数控机床、自动化生产线等。主要目标是掌握PLC在复杂轨迹控制中的应用技巧,提高工业控制系统的精度和效率。 其他说明:文中提到的技术不仅限于画圆,还可以扩展应用于其他复杂的几何图形绘制,如多边形、螺旋线等。并且可以通过进一步优化参数设置,提升系统的响应速度和稳定性。

    chromedriver-mac-arm64-138.0.7153.0.zip

    chromedriver-mac-arm64-138.0.7153.0.zip

    前端测试自动化_跨浏览器兼容性测试工具_基于Nodejs的实时浏览器测试框架_支持多种测试框架和覆盖率统计_用于Web开发中的自动化测试和持续集成_提供稳定可靠的跨浏览器测试解决.zip

    前端测试自动化_跨浏览器兼容性测试工具_基于Nodejs的实时浏览器测试框架_支持多种测试框架和覆盖率统计_用于Web开发中的自动化测试和持续集成_提供稳定可靠的跨浏览器测试解决

Global site tag (gtag.js) - Google Analytics