Web Audio API 失效

不论是录音、还是开启摄像头操作,在 Web 中都要首先调用 getUserMedia 函数来申请权限。这个函数非常特殊,在 Chrome 中,只能是 file:// 或 localhost 或 HTTPS 才能合法的调用它。同时,常常会忽略的是,在 localhost 下需要重新申请麦克风权限才能继续录音。

参考链接

getUserMedia —— Privacy and security 章节

IOS 视频播放黑屏问题解析

IOS 下浏览器播放本网站的视频会出现黑屏。假如在浏览器中直接访问视频文件的地址也出现黑屏,那么你就需要检查一下(通过 POSTMAN 等 HTTP 工具)后端有没有对 Range 请求头做出响应。

产生原因

IOS 下浏览器(Chrome,Safari)在请求视频流时,会默认在 HTTP 请求头中加入 Range 来向服务器请求对应的视频片段。参考这个在线视频链接,IOS 浏览器可以完美播放。使用 Fiddler 在 IOS 下抓包可以看到,在请求这个资源时(单单针对这个视频),手机发出了二次请求。

继续阅读IOS 视频播放黑屏问题解析

Fiddler IOS 抓包保姆级教程

Fiddler 端配置

选择 Tools —— Options——HTTPS,勾选如下配置。

选择 Tools —— Options——Connections,勾选如下配置。注意这里的 8888 为监听端口。

操作系统配置

确认操作系统关闭防火墙,或者开放 8888 端口。

网络配置

确保电脑和手机在一个网络中。在电脑端查看本机 IP 并记录。这里为 192.168.31.55

继续阅读Fiddler IOS 抓包保姆级教程

NGINX 反向代理百度 API

NGINX 反向代理到本机服务做过不少,但很少思考参数的意义。技术债的隐患往往会在特定时候爆发。为了解决如题的问题,我直接把配置改改拿来使用,却发现行不通。

问题

问题在于对于请求头 Host 属性的设置问题。Host 表示的是请求服务器的地址。在转发的时候,可以通过 proxy_set _header 来设置目的地址。

对于转发到本机服务,可以使用 $http_host 来指定本机作为目的地址。但是对于若想转发到非本机服务,Host 需要设置为目的服务所在的主机 IP 或者域名。

在如题所描述的场景中,我需要把请求转发到 vop.baidu.com 这个域名下的 server_api 接口。该接口属于非服务器本机服务,故需要替换 $http_host 为域名 vop.baidu.com。(场景描述 localhost/server_api => vop.baidu.com/server_api)

继续阅读NGINX 反向代理百度 API

使用 Babel Webpack 打造库

Photo by Lê Tân on Unsplash

本人工作后一直采用自顶向下的方法自学编程知识。初期的学习曲线就是直接上手框架加第三方类库,加之这些工具都比较成熟,自带转译(Babel)和打包工具(Webpack),故这两类工具的使用较少。今天在编写自己的类库后发现,使用这两种工具还是有很多问题,故记录分享如下。

工具链逻辑

转译(transpile)。Babel 转译工具的作用是将可在最新的 JavaScript 语法转化为可被旧浏览器运行的兼容代码。转译工具不会处理模块之间的依赖关系。Babel 默认会把 import export 等转译为 require 和 module.exports。

打包。在撰写本文的 2020 年,浏览器对 JavaScript 模块化的支持还是很糟糕,因此需要单独的打包工具来将各个模块聚合在一个文件中。而聚合的线索就是转译工具生成的 require 或者 import 语法。

继续阅读使用 Babel Webpack 打造库

黑苹果 Hackintosh 入门——黑话篇

在折腾了两台黑苹果,一台淘宝付费,一台自己安装,折腾了半个月,黑苹果有点小心得。初入黑苹果,新人遇到的障碍往往是黑话。这里我总结了一些方便查阅。

Clover

MAC OS 在引导的时候会读取主板的固件信息来进入系统。对于 MAC 电脑来说,它们本身的固件信息支持,启动 MAC OS 当然没有问题,而对于普通 PC 来说,我们需要 Clover 来帮助我们动态修改载入到内存的固件信息,加载一些其他驱动,从而欺骗 MAC OS。

OpenCore(OC)

OpenCore。新一代的引导程序。有望替代 CLOVER。个人感觉 OpenCore 的文档更加详细,更利于新手上路。不过目前版本迭代比较快还不稳定,可以继续观望。

S/L/E

指代苹果系统 System/Library/Extentions 目录。里面存放了系统的内核驱动。想要修改此目录,需要关闭苹果 SIP(System Integrity Protection)系统完整性保护的机制。

KEXT

Kenerl Extentions. 特指内核驱动补丁程序,用来驱动显卡、声卡等。可以放在 Clover UEFI 引导文件夹下,也可以通过 Kext Utility 进行安装,否则需要手动重建缓存。

DSDT

Differentiated System Description Tabl。存放在主板固件中,用来描述硬件信息的表。通常由 Clover 或者 OpenCore 自动加载,我们一般也不会直接对其进行修改。

SSDT

Secondary System Description Table。我们可以把它看成是 DSDT 的补丁程序。它也是我们最需要掌握的操作。通过修改 SSDT 我们可以激活黑苹果的电源管理、触摸板、屏蔽独显等操作。

参考资料

Clover 文档

OpenCore 官方文档的解释

OpenCore 对 SSDT 和 DSDT 的解释

Web 安全之浅见

Photo by Ozzie Stern on Unsplash

CSRF(跨域请求攻击) 与 CORS

一旦允许站点跨域请求,就会有 CSRF 问题的出现。CSRF 是指攻击者通过伪造页面的方式,诱导用户点击被伪造的页面,然后在页面中注入目标页面的 URL。一旦用户点击 URL,用户的 Cookie 就会被带上在服务端进行验证。若服务端没有防范非法跨域请求的能力,那么就会导致后台数据在用户不知情的情况下被恶意修改。

庆幸的是,现代浏览器都对非同源请求做了限制,若要启动非同源请求需要,后端服务程序会根据 CORS 对发起的请求进行过滤。只有后端程序允许,才能对跨域请求予以“放行”。

但是值得注意的是,即使服务程序中使用 CORS 来控制 ORIGION 和 REFERER,也无法规避 CSRF 的发生。因为 CORS 不能对表单请求进行预检,同时预检的信息其实也是一种请求,若在预检请求中带上恶意代码也容易造成攻击。

当然防范 CSRF 的方法还有很多,比如后端渲染的页面可以直接在表单上注入随机的 CSRF TOKEN 来校验每一次提交的请求是否合法等。

XSS(跨站脚本攻击)

XSS 主要是指黑客把恶意脚本注入到 URL中,并由后端程序把恶意代码当做参数渲染在页面上返回给浏览器进行执行的一种攻击方式。细分下来主要包含三种不同的形式。

反射型 XSS 。黑客通过电子邮件或者其他社工形式把一个包含恶意代码的 URL 发送给受害者,诱使其点击。后端程序把 URL 上携带的恶意代码当做参数取出并且渲染在页面上。这样一旦用户点击这个 URL 时,浏览器就会执行包含恶意代码的页面。

DOM 型 XSS。和发射型 XSS 一样,黑客通过电子邮件或者其他社工形式把一个包含恶意代码的 URL 发送给受害者,诱使其点击。不同的是,后端程序把 URL 上携带的恶意代码当做参数取出,并赋值给某个脚本变量,返回给受害者,在浏览器端用脚本将恶意代码渲染在页面上并执行。可以看到和发射型 XSS 不同的地方在于恶意代码渲染的时机。

存储型 XSS 。是指黑客精心构造一个包含恶意代码的 URL发送给服务器。后端服务器没有验证 URL 传参中的恶意脚本部分,而是直接把这部分代码存储在数据库中。一旦当其他用户浏览该网站的功能页面,后端程序会把恶意代码从后端数据库中取出并渲染在页面上,从而导致攻击发生。

XSS 与 CSRF

XSS 与 CSRF 的最大区别在于, XSS 是由受害者直接访问目标站点,没有涉及到跨域的问题。漏洞的产生在于服务端没有对URL 中的参数进行校验,从而页面包含恶意代码。而 CSRF 是由受害者无意间向目标服务器发起跨域请求,并使用浏览器存储的 Cookie 饶过验证。漏洞的产生在于后端程序未对跨域的请求进行限制。

参考链接

Using CORS policies to implement CSRF protection

Cross-site scripting

DOM-based XSS 与存储性 XSS、反射型 XSS 有什么区别?

Angular 变更检测 – 深入 OnPush

Photo by Manson Yim on Unsplash

普通策略组件中,引用和事件都会触发 Angular 变更检测。这种策略下,Angular 不会去判断是否应该做而是直接做,因此在一些数据变更比较频繁的场景会有效率问题。为了解决这个难题,OnPush 策略应运而生。在 OnPush 变更检测策略下,引用和部分事件的变化并不会引起变更检测,具体来说:

引用变化

若输入数据的引用没有发生改变,那么这个组件仍然不会触发变更检测更新视图。可以使用 immutable-js 来避免输入数据的引用没有发生变化,从而确保变更检测的发生。

事件触发

和采用 Default 策略的普通组件不同,在 OnPush 策略下,部分事件的触发,并不会主动触发变更检测。包括:setTimeout、setInterval、 Observable、Subscription、Promise.resolve().then() 、 Promise.reject().then() 。

继续阅读Angular 变更检测 – 深入 OnPush

Jenkins + Harbor 容器化持续集成

Photo by Rory McKeever on Unsplash

使用 Jenkins + Harbor 持续集成方案可以在代码仓库有提交时自动对代码进行编译并打包成容器,上传到本地 Harbor,之后 Jenkins 执行 SSH 命令远程控制生产环境从 Harbor 拉取最新容器并运行。

安装 Jenkins 与 Harbor

两者安装文档比较详细。目前主流都是通过 docker 进行部署。

流水线配置

Jenkins 流水线是将一系列动作放在一个配置中完成。在我的场景中我希望做到两点。一是流水线能够由 Git 仓库自动触发动作,自动完成代码的编译和镜像的制作上传。二是在流水线脚本中能够使用 SSH 命令远程访问生产环境主机做拉取容器镜像的操作。

继续阅读Jenkins + Harbor 容器化持续集成

最全 Node 项目 TypeScript 配置

Photo by Lucas Benjamin on Unsplash

此文包含:TypeScript 配置、Nodemon 配置、VSCode 调试配置。

TypeScript 配置

在配置文件 tsconfig.json 中可以指定目标输出、项目根目录路径等,指定 sourceMap 为真方便调试。

Nodemon 配置

可以单独开辟一个 nodemon.json 文件描述配置。这里采用 ts-node 和 path/register 来解决 tsconfig.json 中 baseUrl 不是当前目录的问题。

然后你可以在 NPM Script 中方便的使用 nodemon 来启动项目。

继续阅读最全 Node 项目 TypeScript 配置