# SameSite 防止第三方 Cookie
SameSite 需要通过后台设置 。第三方Cookie
不仅可以用来 CSRF 攻击,还可以用于用户追踪,Cookie
的sameSite
属性用来限制第三方Cookie
,从而减少安全风险。
它可以设置三个值:strict、lax、None
.
Strict 有些过于严格,可能会造成不好的用户体验,Lax 规则稍稍放宽,大多数情况也是不发送第三方 Cookie。
Set-Cookie: CookieName=CookieValue; SameSite=Lax;
# WebApi
客户端 JavaScript 提供很多可用的 API,他们本身不是 JavaScript 语言的一部分,却建立在 JavaScript 语言核心的顶部,为使用 JavaScript 代码提供额外的超强能力。他们通常分为两类:
浏览器 API:内置于 Web 浏览器,可以从浏览器和电脑周围环境获取数据,并用于复杂的操作。例如 Geolocation API 提供了一些简单的 JavaScript 结构来获取位置数据,这种 API 通常抽象很多复杂逻辑,我们只要调用 API 即可。
第三方 API:缺省情况下不会内置于浏览器,而必须在 Wen 中某个地方获取代码和信息,例如 Twitter API 可以推送最新推文给我们,它提供一系列第三方 API 让我们获取 Twitter 的服务和信息。
# Document
# document.execCommand
拷贝选定元素的文本
const copyText = (el) => {
const selection = window.getSelection()
// 清空selection对象
selection.removeAllRanges()
// 创建一个Range实例
const ele = document.querySelector(el)
const range = new Range()
range.selectNodeContents(ele)
// selection对象设置range实例
selection.addRange(range)
document.execCommand('Copy')
selection.removeAllRanges()
}
# History
当hash和query一起使用时,应放在query后边,例:?title=123#id
# Window
# DOMContentLoaded
浏览器DOM树形成之后马上就开始执行业务。
执行时机:DOMContentLoaded事件>readystatechange>load事件,
# load
所有元素加载完才执行
# localStorage
浏览器根据 协议 + 主机名 + 唯一端口(也称为HTML5 Origin)
隔离 LocalStorage 值,也就是说http协议和https协议不共享值
在隐私模式下,localStorage更像是sessionStorage,关闭标签页后就会销毁
localStorage限制大小为5M
LocalStorage 不会阻止同一主机(使用相同的协议和端口)的子域访问他的 LocalStorage 对象。因此,一些浏览器公开了一种解决方法,即授予“a1.website.com
”和“a2.website.com
”它们自己的 5MB LocalStorage 配额。并且由于两个站点位于同一来源,因此它们可以访问彼此的值。(安全方面注意:这也意味着共享域上的站点,例如 apphost.com,都共享一个 HTML5 存储对象。请谨慎操作!)
# SessionStorage
一般情况下SessionStorage会在标签页关闭后销毁,但是浏览器的恢复会话功能会恢复SessionStorage
# WindowBase64
解码:atob
,编码:btoa
# Web Workers API
通过使用 Web Workers,Web 应用程序可以在独立于主线程的后台线程中,运行一个脚本操作。这样做的好处是可以在独立线程中执行费时的处理任务,从而允许主线程(通常是 UI 线程)不会因此被阻塞/放慢。
# Service Worker
由于 Service Worker 设计为完全异步,同步 API(如 XHR 和 localStorage)不能在 Service Worker 中使用
# Element
- Element.getBoundingClientRect() 1.1 方法返回元素的大小及其相对于视口的位置。
# EventTarget
# EventTarget.addEventListener()
addEventListener和on监听事件区别:https://www.cnblogs.com/ontheway1215/p/6842274.html
# Node
# textContent
表示一个节点及其后代的文本内容,与innerText
不同的是:
- 会获取所有机诶安中的每一个元素。相反,
innerText
不会获取隐藏的文本。 - textContent会返回所有元素内容,包括
script
和style
元素内容
# ParentNode
ParentNode.children 是一个只读属性,返回 一个 Node 的子 elements ,是一个动态更新的 HTMLCollection。
可以使用 ParentNode.children.length 获取直接子元素的数量
📚 参考:子元素数量和遍历子元素 (opens new window)
# console
# console.log
支持使用格式说明符:console.log('String: %s, Int: %d,Float: %f, Object: %o', str, ints, floats, obj)
%s 会格式化变量为字符串
%d 会格式化变量为数字
%i 会格式化变量为其整数部分
%o 会格式化变量为对象
%f 浮点数
# console.clear
# console.count
会对打印的字符串的次数进行计数,并在其旁边打印计数
# console.trace
打印堆栈踪迹
const function2 = () => console.trace();
const function1 = () => function2();
function1();
# console.time和timeEnd
计算执行时间,参数为新计时器的名字。 用来标记这个计时器,作为参数调用 console.timeEnd()可以停止计时并将经过的时间在终端中打印出来.
const doSomething = () => console.log('测试')
const measureDoingSomething = () => {
console.time('123')
//做点事,并测量所需的时间。
doSomething()
console.timeEnd('123')
}
measureDoingSomething()
# console.error
错误日志
# URL
https://developer.mozilla.org/zh-CN/docs/Web/API/URL
解析链接,返回host、href、searchParams等
const url = new URL('../cats', 'http://www.example.com/dogs');
console.log(url.hostname); // "www.example.com"
console.log(url.pathname); // "/cats"
# URLSearchParams
https://developer.mozilla.org/zh-CN/docs/Web/API/URLSearchParams
URLSearchParams
接口定义了一些实用的方法来处理 URL 的查询字符串。
var paramsString = "q=URLUtils.searchParams&topic=api"
var searchParams = new URLSearchParams(paramsString);
searchParams.get("topic") === "api"; // true
# 附加组件
# OpenSearch
为浏览器添加网站的搜索引擎.
首先服务器根目录下添加添加 xml 描述文件:
<!-- opensearch.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName>niuyan</ShortName>
<Description>搜索牛眼</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16" type="image/x-icon">http://web.pre.niuyan.com/favicon.ico</Image>
<Url type="text/html" template="http://web.pre.niuyan.com/zh/search/{searchTerms}">
</Url>
</OpenSearchDescription>
然后在 html 中添加引用,title
字段要和xml
文件中的ShortName
一致:
<link
type="application/opensearchdescription+xml"
href="opensearch.xml"
title="niuyan"
rel="search"
/>
👽 差异:
在 firefox 中访问页面后需要在搜索框中添加 opensearch,而在 chrome 中访问项目的主页就会自动添加,主页地址必须是www.test.com
,而不能是www.test.com/zh
⚠️ 注意:
- 如果 opensearch 如果没有生效,试试清除 xml 文件的缓存
- opensearch 不能自定义触发关键词
📚 引用:
opensearch-1-1-draft-6 (opens new window)
# sessions
session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而session保存在服务器上。
# 工作流程
浏览器访问服务器并发送第一次请求时,服务器端会创建一个session对象,生成一个类似与key,value的键值对,然后将key(cookie)返回到浏览器(客户)端,浏览器下次再访问时,携带key(cookie),找到对应的session(value)。客户的信息都保存在session中。
# 问题
# 为什么链接、图片和文字默认可以拖拽?
这是浏览器的默认行为,这种行为可以把图片链接等拖拽到标签栏或者搜索栏,来单独显示图片或者打开链接
# 如何在开发者工具中查看placeholder样式?
在chrome中:
- 进入开发者工具界面
- 点击小齿轮设置
- 勾选
Elements
中的Show user agent shadow DOM
- 刷新页面,查看input元素下边多了个placeholder shadow dom,点击就可以查看placeholder的样式了
# 浏览器显示的 json 对象顺序与实际不同?
本身对象属性是没有顺序的,但是 chrome 按照 ASCll 码顺序进行了排序显示。
# 对同一个 URL 提出多个同一个请求,会延迟完成?
谷歌浏览器同时只能对同一个 URL 提出一个请求,如果有更多的请求的话,则会串行执行。如果请求阻塞,后续相同请求也会阻塞。
# 元素全屏后并没有占满全屏幕?
WebKit 浏览器 会让全屏的元素以原始尺寸居中到屏幕中央,其余部分变为黑色(没有为该元素设置 background style 时)。要在 WebKit 浏览器中获得正常的全屏行为,您需要添加全屏时的样式,例如:
#test:-webkit-full-screen {
width: 100%;
height: 100%;
}
# ServiceWorkers/WebWorkers/WebSockets 的区别
ServiceWorkers/WebWorkers/WebSockets 的区别 (opens new window)
# 如何让元素失去焦点?
document.activeElement
可以获取当前焦点元素。使用document.activeElement.blur();
可以失去焦点,通常用于隐藏webview键盘。
# scrollTo到顶部失效?
原因是为body设置了110vh,改成px就没有这个问题了。
# web 安全
# 同源策略
跨域的 9 种方式:
jsonp,原理:利用
<script>
标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP 请求一定需要对方的服务器做支持才可以。cors
postMessage
websocket
node 中间件,原理:同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。
nginx 反向代理,原理:类似于 Node 中间件代理,需要你搭建一个中转 nginx 服务器,用于转发请求。
window.name + iframe
location.hash + iframe
document.domain + iframe
# chrome90版本之后无法设置cookie
- 先退出浏览器 再 open -a "Google Chrome" --args --disable-features=SameSiteByDefaultCookies
# 最佳实践
# addEventListener和on注册事件
优先使用addEventListener
# 获取某个元素相对于视窗的位置
Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。
# 获取元素所有子孙元素数量
document.getElementsByTagName("*").length
# 获取url参数对象
const url = 'http://example.com/search?name=zhangsan&age=19'
const query = Object.fromEntries(new URL(url).searchParams.entries())
# 兼容性
1.使用caniuse查看特性在不同浏览器上的支持性,android 4.4之后使用chromium,所以支持度可以和chrome看齐
html 和 css 各种补全垫片库 (opens new window) js 和 dom 补全 (opens new window)