随着微软发布基于 Chromium 的 Edge 以及 Edge WebView2 Runtime,Chromium 在 Windows 桌面上扮演着越来越重要的角色。在日常工作中,当用户打开了 Outlook 收发邮件、Teams 进行会议以及 Edge 浏览网页时,操作系统上就已经同时运行着 3 个 Chromium 的实例了。在企业环境中如果配置了系统使用 PAC (代理自动配置)脚本,在当今的这种 Chromium 普惠生态环境中可能会对部署 PAC 脚本的服务器带来较大的请求压力。
在管理企业 IT 环境时,经常需要安装或重现特定版本的软件,以便模拟客户的环境,进行故障排查或测试。最近,我遇到了一个需要安装特定版本的 Office 365 的情况。在这篇博客中,我将分享我的经验和学到的技巧。
在软件开发中,选择最有效的方法来解析大型数据集对于提高性能至关重要。我进行了一个实验,比较了使用 Node.js 统计大型文本文件中换行符数量的两种不同方法:使用 indexOf
和手动逐字节检查。
如果你曾经开发过 HTML 邮件,那你可能知道这是一个挑战。与现代的网页浏览器大致遵循网络标准不同,像 Microsoft 的 Outlook 这样的邮件客户端有其独特的特点,可能会使你精心制作的邮件看起来与你预期的不同。
随着 IE11 的退役,许多 Windows 用户发现自己无法通过传统的在 IE 中打开网页并检查页面属性的方式来判断一个 URL 属于什么 Security Zone 了。这对于系统管理员和安全分析师来说是一个相当大的不便,因为 Security Zone 是判断 URL 是否安全,以及它们如何与系统的安全策略交互的重要因素。
近日,我进行了 WiFi7 无线网卡的识别测试,遇到了一些有趣的问题和解决方案,与大家分享。首先,以往我们在 Windows 上识别网卡属性,经常使用的是 Win32_NetworkAdapter 类。只要其中返回的 PhysicalAdapter
属性为 true
,我们就可以判断这是一张物理网卡。但是在 WiFi7 网卡上进行相同的测试时,我发现 Win32_NetworkAdapter
返回的所有 PhysicalAdapter
属性都是 false
。进一步的研究表明,Win32_NetworkAdapter
其实已经被标记为过时,现在推荐使用的是 MSFT_NetAdapter 类。
在使用 TypeScript 进行开发时,精确的类型检查是常态,这有时需要重复的类型断言来告诉编译器我们对变量类型的“了解”。尽管这种强大的类型系统提高了代码质量,但有时也会变得很冗长,尤其是在处理 DOM 元素时。本博客文章旨在介绍 TypeScript 中的一项功能,即用户自定义类型守卫,它能减少代码冗余,使您的 TypeScript 代码更加易读和可维护。
针对经常出现的 Edge 或 Edge WebView2 升级和安装问题,我在此分享一篇文章来帮助大家更好地理解 MicrosoftEdgeUpdate.log
中的常见场景。
在开发环境中,我们可能需要生成自己的证书颁发机构(CA)和 SSL 证书进行测试。这些指令使用了 OpenSSL,这是一款强大的 SSL 和 TLS 协议工具包。下面我详细介绍了如何在 Windows 上创建这些证书,但类似的步骤也可以应用在不同的平台上。
最近部署在 Azure 上的 VM 经常因为某些原因被停用(Deallocated),遂想着写一个 PowerShell 脚本配置为 Windows 的计划任务来监控 Azure VM 的状态,一旦发现被停用了,自动启动 Azure VM。该脚本将用到 Azure PowerShell
提供的命令集,通过预先创建的 Azure service principal
来自动登录并获取 VM 状态,如果状态是 deallocated
就调用 Start-AzVm
命令来启动 VM,每次运行结果都会记录到本地日志。
最近购入了华为荣耀智慧屏电视,由于 3 年前买的微鲸电视都自带局域网访问功能,我以为这已经是当今所有智能电视自带的功能,却没想到智慧屏自带的媒体中心只能读取本机文件和 U 盘上的文件,并不具备局域网访问能力,导致无法访问家里 NAS 服务器上的海量资源,看来这个智慧屏一点都不智慧。网上调查了下发现许多智慧屏用户都有同样的痛点,也不清楚华为是否会在将来的更新中给媒体中心加上局域网访问的支持,起码在现在最新版本 HarmonyOS 1.0.1.23(SP2) 中是不支持的。首先我看到有人推荐使用 ES 文件浏览器,我试了下的确支持 SMB 访问,但是又碰到了闪退的问题,并且其自带的媒体播放器也不能播放 RMVB 格式,遥控器控制快进、快退也不顺畅,所以并不是个很好的解决方案。经过几番测试,终于找到到了目前为止可以说近乎完美的智慧屏访问 NAS 的解决方案,那就是 VLC。
最近碰到一个 Edge 浏览器不工作的问题,Edge 打开后无法访问任何站点,一直报错:“这很奇怪...有些东西停止工作,所以这个页面无法加载。”,详细信息为:“无法创建内容处理,错误代码:0x8027025b”。这个问题是由于系统文件夹 C:\Windows\System32
缺少了所有受限制的应用程序包
的权限以及注册表:HKEY_LOCAL_MACHINE\Software
缺少了 S-1-15-3-1024-1065365936-1281604716-3511738428-1654721687-432734479-3232135806-4053264122-3456934681
权限所导致。这篇文章将讲述如何修复这两个特殊账户权限丢失的问题。
最近我开始支持 Microsoft JDBC Driver for SQL server,它能够使 Java 应用连接到微软 SQL Server。由于从未接触过 Java 开发,所以写下这篇文章记录如何创建一个最简单的控制台 Java 程序通过 JDBC Driver 来连接 SQL Server。
为了确保数据通信的安全,HTTPS 已广泛应用于互联网,浏览器与服务器之间的 HTTPS 通信都是加密的。然而当浏览器需要通过代理服务器发起 HTTPS 请求时,由于请求的站点地址和端口号都是加密保存于 HTTPS 请求头中的,代理服务器是如何既确保通信是加密的(代理服务器自身也无法读取通信内容)又知道该往哪里发送请求呢?为了解决这个问题,浏览器需要先通过明文 HTTP 形式向代理服务器发送一个 CONNECT 请求告诉它目标站点地址及端口号。当代理服务器收到这个请求后,会在对应的端口上与目标站点建立一个 TCP 连接,连接建立成功后返回一个 HTTP 200 状态码告诉浏览器与该站点的加密通道已建成。接下来代理服务器仅仅是来回传输浏览器与该服务器之间的加密数据包,代理服务器并不需要解析这些内容以保证 HTTPS 的安全性。
最近在做一个工具自动把外部的Web Worker文件引用内联化,即碰到代码里有new Worker('worker.js')
,就去读取worker.js
的代码,然后把原Web Woker引用内联化为:new Worker(window.URL.createObjectURL(new Blob(["/* worker.js的内容 */"])))
。这个功能看似简单,我一开始想用正则表达式来匹配出Web Worker的实例化参数,但发现有很多极端情况需要去做特殊考虑,最终在了解并尝试了JavaScript AST(Abstract Syntax Tree抽象语法树)Parser后,所有的问题迎刃而解。
最近正在做一个基于浏览器 File Reader API 的文本解析工具。为了让繁重的文本解析工作不影响页面线程的性能,使用 Web Worker 来负责处理文本解析应该是最优的。Web Worker 需要将解析后的每行文本传回给页面,当需要传输的文本行数达到数十万、百万行时,性能问题就变得尤为重要,一方面是传输的耗时,一方面是内存的消耗。多数浏览器实现了结构克隆,允许你对 Web Worker 传入、传出更复杂的数据类型,如:File, Blob, ArrayBuffer, JSON 对象等。然而当你使用postMessage()
方法传输这些数据时,数据会被拷贝一份再进行传输,所以当你传输 100MB 的数据时,主进程和 Worker 进程都会增加 100MB 的内存使用,并且复制 100MB 的数据需要的时间可能达到几百毫秒。为了解决这个问题,postMessage()
方法也支持传输 Transferable 数据类型,使用 Transferable 传输时,会直接把数据从一个执行环境(Worker 线程或主线程)传输到另一个执行环境,这样不会额外增加一份内存消耗,并且传输速度极快因为不需要数据拷贝。可是在实际使用中,如果需要传输大量的 Transferable 数据时,这种方法仍存在显著的性能问题。
HTML5 的FileReader
API 可以让客户端浏览器对用户本地文件进行读取,这样就不再需要上传文件由服务器进行读取了,这大大减轻了服务器的负担,也节省了上传文件所需要的时间。不过在实践中我发现用FileReader.readAsText()
可以轻易地处理一个 300k 的日志文件,但当日志文件有 1G、甚至 2G 那么大,浏览器就会崩溃。这是因为readAsText()
会一下子把目标文件加载至内存,导致内存超出上限。所以如果 Web 应用常常需要处理大文件时,我们应该使用FileReader.readAsArrayBuffer()
来一块一块读取文件。
匿名函数作为参数在JavaScript是很常见的,事件绑定、异步回调等都会用到匿名函数。ES6中引入了箭头函数,用于便捷地书写匿名函数。大致语法为:(参数) => {表达式或返回值}
,接下来让我们来看看箭头函数的用法。
JS中的对象类型:var obj = {a:1}
,可以通过变量.属性名
的形式进行取值、赋值,这种方式虽然便捷,但其创建的属性值可以被任意修改,并可以通过for...in
枚举。__Object.defineProperty()__可以定义、修改对象属性的值及其特性。如今流行的数据双向绑定的JS库中广泛使用了该方法。
升级至 IE11 后网页布局破坏最常见的原因是:IE11 使用了较新的文档模式来渲染页面。但有时候会发现一个页面即使使用了相同的文档模式,IE11 中显示的布局仍然被破坏了,这可能是由于 IE11 使用了一种全新的字体渲染模式:natural metrics
,在 IE11 之前 IE 都是使用传统的gdi metrics
。
有些 IE、IIS 的问题会牵涉到客户端证书,每次搭建一个要求客户端证书的网站测试环境都要花费较长时间,痛定思痛决定把所有步骤:创建自签名根证书、服务端证书、客户端证书、配置 IIS 记录下来。
我之前使用过 Visual Studio 来部署 Azure Web 站点,VS 和 Azure 的高度集成使网站部署变得十分简单。然而我另一个站点是通过 Gulp 自动构建静态页面、文件的,所以我希望能通过一条命令使 Gulp 自动完成网站的部署,如:gulp deploy
。Azure Web 站点的部署方式有很多选择:Visual Studio、Git、Powershell、FTP、手动部署等。在权衡了利弊之后,我决定采用 Gulp+Git 来实现自动部署站点。每个 Azure Web 站点都允许创建一个 Git 仓库作为部署源,不过这个选项默认是关闭的,Local Git Deployment to Azure App Service介绍了如何从管理界面中开启 Git 仓库以及如何通过 Git 命令将本地站点发布到 Azure 上。本文将重点介绍如何使用 Gulp 将文中的手动部署操作转为自动化脚本。
在调试 Node.js 项目时,每次修改代码都要重新运行node server.js
才能生效,大大降低了效率。我们可以使用 nodemon 来通过监测文件变化自动重启 node。
在 IE11 中,仅仅使用兼容性视图可能无法解决所有兼容性问题。2014 年 4 月的 IE11 累积更新首次引入了企业模式。起初企业模式旨在模拟 IE7、IE8 浏览器行为以兼容更多的老旧站点,之后的更新中企业模式允许针对某个站点指定使用特定的文档模式(5~11)。所以为了使用到功能最全面的企业模式,请先将 IE11 更新至最新版本:KB4018271。
最近正在做 HTTP/2 相关的研究,由于目前所有的浏览器仅支持在 HTTPS 上使用 HTTP/2,所以通过 Wireshark 只能查看到加密后的 TLS 网络包。其实 Wireshark 提供了一些设置允许我们解码 TLS、SSL 网络包。
兼容性视图是 IE 最常用的向下兼容方案,它可以通过兼容性视图设置、组策略、本地 Intranet 站点来实现。巧妙地利用这些配置可以控制不同的子域名有些在兼容性视图中显示,有些在默认模式中显示。
浏览器模式决定了 Internet Explorer 发出请求时自带的 User-Agent,也决定了在默认情况下 Internet Explorer 使用哪一种文档模式来渲染页面。这篇文章就来梳理一下它们的关系。
最近在 IE11 中遇到网页不工作并报错: “SEC7111: HTTPS 安全受到(null)的威胁” 的问题。调试后发现这是由于在 HTTPS 页面调用 document.write()
方法所导致。
ECMAScript 2015 (ES6) 提供了一种更加严谨的变量声明方法: let 用于取代之前的 var。 let 声明的变量作用域为所处的块级内而不像 var 作用于整个函数体内。虽然 var 的使用是相当宽松的,但这种特性往往会带来许多意想不到的bug,尤其是在一个复杂的工程中。本文将比照 var 来介绍一下 let 的特性。
在绑定onscroll事件时,我们应当着重关注其性能问题,因为onscroll与其他的鼠标、键盘等事件相比,它被触发的频次很高,间隔很近。如果onscroll事件中涉及到大量的位置计算、元素重绘等工作且这些工作无法在下一个onscroll事件触发前完成,就会造成浏览器掉帧。加之用户鼠标滚动往往是连续的,就会持续触发onscroll事件导致掉帧扩大、浏览器CPU使用率增加、用户体验受到影响。由于开发人员的机器配置普遍都不错,可能同一个onscroll的事件在开发机上只需要10ms,然而在普通配置的机器上需要30ms,因此这类问题常会被开发人员忽视。这篇文章将介绍如何避免onscroll事件潜在的性能问题。
最近我在往博客文章中添加评论功能后,发现使用 IE 访问某一篇文章的页面总是弹出警告:“Internet Explorer 已对此页面进行了修改,以帮助阻止跨站点脚本”。通过 Fiddler 不断调试和测试,发现是因为这篇文章的标题以 JavaScript:
开头,然后触发 IE 的 XSS 筛选器认为这是一个跨站点脚本攻击。其实文章标题中并不含有任何 JavaScript 脚本语句,只不过是以 JavaScript:
为开头,却最终导致 XSS 筛选器误判一个正常的页面。
网页中引用的外部文件: JavaScritp、CSS 等常常会阻塞浏览器渲染页面。假设在 <head>
中引用的某个 JavaScript 文件由于各种不给力需要2秒来加载,那么浏览器渲染页面的过程就会被阻塞2秒,直到该JS文件下载并执行完后才继续。前端性能调优时必须排除任何潜在的渲染阻塞点,让浏览器在最短时间内渲染出整体页面。
当浏览器请求一个之前访问过的静态文件时,会在 HTTP 头中加上:If-Modified-Since、If-None-Match以向服务器确认该文件是否有更新,如果没有更新,服务器则返回 304 Not Modified,浏览器就会使用本地缓存而不是从服务器重新下载该文件。这是多数 Web Server 对于静态文件的默认缓存行为,然而这个缓存行为仍有优化空间。默认的缓存行为依然需要浏览器与服务器建立一个 HTTP 连接以确定每个文件是否更新过,从客户端建立连接、发送连接、服务器判断文件状态到最终客户端收到 304 Not Modified 之间仍需要几十甚至上百毫秒并且消耗一定的服务器资源。
使用JavaScript操作DOM元素时往往涉及到两个概念:attribute 和 property。 document.getElementById('test').getAttribute('id')
、 $('#test').attr('id')
、 document.getElementById('test').id
和 $('#test').prop('id')
都能返回正确的id:"test"。这篇文章主要介绍一下 property 和 attribute 的区别以及如何使用。
自 2016 年 1 月 12 日起,Windows 7 上的旧版本 IE 浏览器(8~10)将停止支持。越来越多的企业和个人用户选择升级至最新的 Internet Explorer 11,对于个人用户,升级 IE11 只需点几下鼠标。然而对于企业 IT 管理员,升级成百上千台计算机的 IE 并且确保成功,那可能就没那么容易了。