实现符合 HTTP access control (CORS) 规范的跨域请求配置

其中 crossDomain: true 属性,可禁止添加 X-Requested-With: XMLHttpRequest 自定义请求头。默认情况下,对于非跨域请求会添加,对于跨域请求不添加。
其中 withCredentials: true 属性,可控制 XMLHttpRequest 对象,携带 other.domain 域下的凭证信息(如 Cookie 等)。
对于简单请求,会直接发送指定类型的请求。对于预请求,会先发出一个 OPTIONS 请求,得到成功回应后才发送指定类型的请求。

根据前端提供的请求头,后端返回对应的响应头。对于 OPTIONS 请求,注意不要执行业务代码。
对于前端未授权的同步(如访问 html 页面)请求,后端可直接 302 跳转至登录页。对于前端未授权的异步(如 json 接口)请求,后端应仍然输出 json 结构响应,可在该结构中定义代表需要登录的状态码。
对于异步请求的检查,建议使用请求后缀(如 json 后缀)检查。不建议使用请求头(如 X-Requested-With 自定义头)检查,因为对于预请求,是不会携带该自定义头的。

IOS10下Safari中的页面,其viewport配置user-scalable=no无效。

IOS10发布后,苹果为了“用户体验”,在Safari中忽略了user-scalable=no配置,但在WebView中仍默认启用。
为了“邪恶的阻止用户得到更好体验”,只能通过脚本方式在Safari中禁用缩放了。

参考资料:
iOS SDK Release Notes for iOS 10.0
ignoresViewportScaleLimits

异步跨域 cookie 在 IOS 和 Andriod 的 Safari 或 WebView 中无法写入

跨域配置:
当入口页面与后端接口没有部署在同域(协议/域名(IP)/端口)时,需要进行跨域配置。
简单请求时,不能携带跨域凭证信息(如 cookie ),只需要后端接口返回 Access-Control-Allow-Origin:* 协议头即可。
预请求时,可携带跨域凭证信息(如 cookie ),但需要前端异步请求设置 withCredentials=true 标志,后端接口返回 Access-Control-Allow-Credentials:true 和 Access-Control-Allow-Origin:http://example 协议头,不能使用 * 占位符。
以上配置在标准浏览器实现中可正常使用,如 Andriod 6.0 平台的 Chrome 或系统自带浏览器都没问题。但 Andriod 6.0 平台的 WebView 以及 IOS 10 平台的 Safari 浏览器和 WebView 在使用“预请求”模式时,无法写入跨域 cookie 。
查询资料后发现是第三方 cookie 的隐私策略造成。 Android 5.0 之后,对于 WebView 需调用 setAcceptThirdPartyCookies 方法, IOS 7.0 之后,对于 WebView 需设置 setCookieAcceptPolicy 配置,允许第三方 cookie 存储。
变通的解决方案是,用户访问后端域下的中转页,中转页写入(非 Session 级别?) cookie 并(302/meta/js)跳转至前端域下的入口页面,此时入口页面即可正常使用“预请求”模式。
注意 Safari 开发人员工具中记录的 request 通讯,似乎并未正确显示应携带的跨域 cookie 数据,但后端确实接收到了该数据。

参考:
HTTP访问控制(CORS)
苹果手机IOS全版本safari浏览器和Android 6.0 Webview 跨域请求(CORS)时,不带cookies问题
Android 5.0 行为变更
Cookies and Custom Protocols
第一方Cookie和第三方Cookie区别
关于p3p简洁策略,以及浏览器的支持情况.
记一次iphone 微信内置浏览器跨域无法获取cookie问题的解决方法
safari浏览器cookie问题

Chrome在Mac和Windows下,对中国标准时间(CST)和中国夏令时(CDT)的不同处理。

通过接口从后端获取时间戳,在前端用JS格式化显示。发现Chrome在Mac和Windows下,对特定的时间段(1986年至1991年),的处理方式并不相同。

查询资料后发现,原来中国也曾经使用过夏令时。

1986年至1991年,中华人民共和国在全国范围实行了六年夏令时,每年从4月中旬的第一个星期日2时整(北京时间)到9月中旬第一个星期日的凌晨2时整(北京夏令时)。除1986
年因是实行夏令时的第一年,从5月4日开始到9月14日结束外,其它年份均按规定的时段施行。1992年4月5日后不再实行。

要避免此情况可在后端对时间进行处理,返回格式化后的日期字符串。

或在前端通过getTimezoneOffset检测夏令时,尝试网上找到的夏令时检测算法。

参考资料:
时间是什么?
java中的时区陷阱
Java —— 时区(夏令时)问题
CST和GMT时间的区别
使用 JavaScript 处理夏令时
js获得当前时区夏令时发生和终止的时间
List of time zone abbreviations
tz database
Daylight saving time
Time in China
Time zone
ISO 8601

DOM级别 事件捕获 事件冒泡 阻断事件传播 阻止默认行为 自定义事件

事件处理兼容性函数


EventTarget

Legacy Platform Events
理解JavaScript中的事件处理
关于DOM级别的一些问题

自定义事件

Document.createEvent()
CustomEvent
创建和触发 events
javascript自定义事件(event)

jQuery事件核心

解密jQuery事件核心 – 绑定设计(一)
解密jQuery事件核心 – 委托设计(二)
解密jQuery事件核心 – 自定义设计(三)
解密jQuery事件核心 – 模拟事件(四)