?Cookie 從入門到進階:一文徹底弄懂其原理以及應用

大家好,我是若川。持續組織了8個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。歷史面試系列

Cookie 是什么?

fb2d91c0832aa5f1d3adf72dd7975871.png

Fortune cookie

Cookie,它的名字源自一種叫 Fortune cookie 的餅干,這種餅干里面有一張寫著精辟句子的小紙條。

在瀏覽器中,Cookie 是服務器讓瀏覽器幫忙攜帶信息的手段,就像餅干里的紙條,瀏覽器會儲存它,并且在后續的 HTTP 請求中再次發送給服務器

3cc24b2d2299c9c272e9a1812cc387c9.png

36d3890f9f38142e94b141467c154835.png

Cookie 應用

主要用于以下三個方面:

  • 會話狀態管理(如用戶登錄狀態、購物車、游戲分數或其它需要記錄的信息)

  • 個性化設置(如用戶自定義設置、主題等)

  • 瀏覽器行為跟蹤(如跟蹤分析用戶行為等)

因為 HTTP 是無狀態的,所以為了協助 Web 保持狀態,Cookie 誕生了。在 HTML5 的 localStorage、sessionStorage 出現之前,它作為當時唯一的儲存手段也曾一度被用于客戶端儲存。

隨著瀏覽器儲存機制的完善,為了減小不必要的性能開銷(因為每次請求瀏覽器都會攜帶 Cookie 數據),一些客戶端需要而服務器不需要的數據的場景漸漸被其他儲存方式替代,例如記住用戶的主題信息,Cookie 的應用場景也漸漸回歸初心。

目前 Cookie 主要用于會話狀態管理,以用戶登錄-退出登陸為例,Cookie 的生命周期如下:

前端通過用戶登錄 API 向后端傳遞用戶信息,后端核對與數據庫信息是否匹配。

匹配后在登錄 API 返回頭部 set-cookie 返回記錄用戶狀態的 cookie 值 userToken:

ae8ac1e77d2b4fa785fe550cf18b27e5.png

瀏覽器按照 set-cookie 的規則解析后存入瀏覽器

829bdaa2f80f9ef38c835643d41eed20.png

后續瀏覽器會自動將 userToken 加到滿足條件(域名、路徑)的 API 的 請求頭部 cookie 中

46f177354e89fd7259ce55d070a467db.png

如果退出登陸,返回頭部的 set-cookie 會拜托瀏覽器幫忙刪除 userToken,瀏覽器的 cookie 儲存庫就會將 userToken 字段刪除,后續的 API 請求頭部 cookie 也不會發送它

a0cd28873dea3a774e7723e4c94aa84f.png

如何設置 Cookie

服務端和瀏覽器有不同設置 Cookie 的方式。

速查表

平臺操作示例說明
服務端set-cookie: <cookie-name>=<cookie-value>服務端通過設置 set-cookie 控制 Cookie
瀏覽器
document.cookie
document.cookie = "name=scar";獲取并設置與當前文檔相關聯的 cookie,操作不靈活。
瀏覽器
Cookie Store API
cookieStore.set("name", "scar")新特性,僅支持在 HTTPS 使用,目前還在實驗階段。

詳細說明

服務端:Set-Cookie

服務端以 Node.js 為例,不同語言有不同的用法,但 Cookie 設置邏輯是一樣的

const?http?=?require("http");
http.createServer((req,?res)?=>?{if?(req.url?===?"/read")?{//?讀取?Cookieres.end(`Read?Cookie:?${req.headers.cookie?||?""}`);}?else?if?(req.url?===?"/write")?{//?設置?Cookieres.setHeader("Set-Cookie",?[`name=scar;`,//set-cookie?屬性大小寫不敏感,你可以寫成?path=/?或者?Path=/`language=javascript;Path=/;?HttpOnly;Expires=${new?Date(Date.now()?+?1000).toUTCString()};`,]);res.end("Write?Success");}?else?if?(req.url?===?"/delete")?{//?刪除?cookieres.setHeader("Set-Cookie",?[//?設置過期時間為過去的時間`name=;expires=${new?Date(1).toUTCString()}`,//?有效期?max-age?設置成?0?或?-1?這種無效秒,讓?cookie?當場去世//?有些瀏覽器不支持?max-age?屬性,所以用此方法需要考慮兼容性"language=javascript;?max-age=0",]);res.end("Delete?Success");}?else?{res.end("Not?Found");}}).listen(3000);

客戶端:document.cookie

客戶端通過瀏覽器方法 document.cookie 讀寫當前界面的 Cookie。

//?編輯?ookie
document.cookie?=?"name=scar";
document.cookie?=?"language=javascript";
//?讀取?Cookie
console.log(document.cookie);
//name=scar;?language=javascript//?刪除?Cookie
document.cookie?=?"name=scar;expires=Thu,?01?Jan?1970?00:00:01?GMT";

客戶端:Cookie Store API

Cookie Store API 目前正在試驗階段,Firefox、Safari 瀏覽器 還不支持,所以不建議在生產環境使用,相信在將來我們會用上它更方便地操作 Cookie。

//?讀取?Cookie
await?cookieStore.get("enName");
await?cookieStore.getAll();//?設置?Cookie
const?day?=?24?*?60?*?60?*?1000;
cookieStore.set({name:?"enName",value:?"scar",expires:?Date.now()?+?day,domain:?"scar.site?",}).then(function?()?{console.log("It?worked!");},function?(reason)?{console.error("It?failed:?",?reason);});//?刪除?Cookie
await?cookieStore.delete("session_id");//?監聽?Cookie?變化
cookieStore.addEventListener("change",?(event)?=>?{for?(const?cookie?of?event.changed)?{if?(cookie.name?===?"name")?sessionCookieChanged(cookie.value);}for?(const?cookie?of?event.deleted)?{if?(cookie.name?===?"enName")?sessionCookieChanged(null);}
});

除了更方便的用法,他還有以下特性:

異步操作

它可以異步訪問 Cookie,不阻塞主進程,document.cookie 是同步操作。

錯誤拋出機制

Cookie Store API 有一個明確的機制來報告 Cookie 存儲錯誤,而 document.cookie 如果設置失敗也不會提醒,所以需要輪詢查 Cookie 的方法來確保設置成功。

service workers 支持

因為 document.cookie 的同步設計,所以 service workers 不支持。Cookie Store API 的異步特性更適合,所以 service workers 支持通過它訪問 Cookie。

Set-Cookie 詳解

從語法可以看出,Set-Cookie 由前綴、鍵值對、屬性三部分組成。

Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>// 同時指定多個屬性 Domain、Secure、HttpOnly
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly// cookie 前綴,值可能性為 __Secure-、__Host-
Set-Cookie: <cookie-prefix><cookie-name>=<cookie-value>
  • 前綴[非必須]

    • 示例:Set-cookie: __Secure-lol=foo;Domain=example.xxx, _Sercure- 就是前綴

    • Cookie 前綴需配合屬性使用,使 Cookie 更安全

  • 鍵值對(名稱=值)

    • 示例:Set-cookie: __Secure-lol=foo

    • Cookie 攜帶信息

  • 屬性[非必須]

    • 示例:Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT

    • Cookie 的設置,告訴客戶端如何使用 Cookie 信息,可以設置 Cookie 生效的時間、域名等等信息。

Cookie 前綴

Cookie 前綴是一種在 Cookie 名稱中攜帶信息的方式,它必須和某些屬性同時出現,否則 Cookie 無法設置成功。

名稱說明
__Secure-必須同時設置 Secure 屬性
__Host-必須同時設置 Path=/ 和 Secure 屬性,且不能設置 Domain 屬性。
限制來自安全域的 Cookie 被作用在不安全的域上

例子:

//?支持?Cookie?前綴的收到下面設置的時候會拒絕,因為沒有同時設置?Secure?屬性
document.cookie?=?"__Secure-invalid-without-secure=1";
//?這樣設置才能成功!
document.cookie?=?"__Secure-valid-with-secure=1;?Secure";
// 當響應來自于一個安全域(HTTPS)的時候,二者都可以被客戶端接受
Set-Cookie: __Secure-ID=123; Secure; Domain=example.com
Set-Cookie: __Host-ID=123; Secure; Path=/// 缺少 Secure 屬性,會被拒絕
Set-Cookie: __Secure-id=1// 缺少 Path=/ ,會被拒絕
Set-Cookie: __Host-id=1; Secure

說實話這個前綴我之前從沒見過,孤陋寡聞了。

除了 IE 不支持,其他各大瀏覽器基本支持。不同瀏覽器限制可能不同,例如:Set-Cookie: __Host-id=1; Secure設置 __Host-前綴的時候,即使缺少 Path=/,FireFox 可以設置成功,而 Chrome 會拒絕。

但為什么有 Secure 屬性還要加個 __Secure- 前綴呢?

因為 Secure 屬性設置后是可以被人惡意移除的,而 Cookie 名稱被人移除前綴,服務器不會認它,所以更加安全。

Cookie 鍵值對

<cookie-name>=<cookie-value>

真正攜帶信息的部分,例如:

id=38afes7a8

<cookie-name>? 可以是除了控制字符 (CTLs)、空格 (spaces) 或制表符 (tab)之外的任何 US-ASCII 字符。同時不能包含以下分隔字符:( ) < > @ , ; : \ " /? [ ] ? = { }。

<cookie-value>? 非必填,如果有值,那么需要包含在雙引號里面。支持除了控制字符(CTLs)、空格(whitespace)、雙引號(double quotes)、逗號(comma)、分號(semicolon)以及反斜線(backslash)之外的任意 US-ASCII 字符。

Cookie 屬性

Cookie 屬性可以理解為 Cookie 的配置項,告訴瀏覽器 Cookie 的一些額外信息,例如什么時候失效

速查表

Cookie 屬性說明類型默認值示例
Domain生效域名String當前訪問地址中的 host 部分scar.site
Path生效路徑String//docs
Expires過期時間Date瀏覽器會話關閉時間Thu, 22 Jul 2021 00:53:13 GMT
Max-Age有效期,單位秒Number
1000
Secure僅 HTTPS 可用

無值,出現即設置
HttpOnly設置了 HttpOnly 屬性的 cookie 不能使用 JavaScript 進行訪問

無值,出現即設置
SameSite允許服務器設定 Cookie 不隨著跨站請求一起發送stringLax值可能性為:
Lax
Strict
None
SameParty允許特定條件跨域共享 Cookie

無值,出現即設置
Priority優先級,僅 Chrome 支持
Medium值可能性為:
Low
Medium
High

詳細說明

Domain

Domain?指定了哪些主機地址可以接收 Cookie。來看看如下設置:

Set-Cookie: __Secure-ID=123; Secure; Domain=example.com

表示只要請求的目標地址匹配 Domain 規則,那 Cookie 就會被發送過去,所即使scar.siteexample.com 發起的請求,Cookie 會被發送過去。所以不要再誤會 Domain是發起請求的域名啦,其實是接受請求的域名

如果不設置,默認為?origin,不包含子域名,如果指定了Domain,則一般包含子域名,例如,如果設置?Domain=mozilla.org,則 Cookie 也包含在子域名中(如developer.mozilla.org)。

當前大多數瀏覽器遵循?RFC 6265,設置 Domain 時 不需要加前導點。瀏覽器不遵循該規范,則需要加前導點,例如:Domain=.mozilla.org

Path

Path?標識指定了主機下的哪些路徑可以接受 Cookie(該 URL 路徑必須存在于請求 URL 中)。以字符?%x2F?("/") 作為路徑分隔符,子路徑也會被匹配。

例如,設置?Path=/docs,則以下地址都會匹配:

  • /docs

  • /docs/Web/

  • /docs/Web/HTTP

Expires

設置過期時間,可以傳一個符合 HTTP-Date 格式的值,例如:expires=Mon, 14 Mar 2022 15:39:34 GMT;

如果不設置 Expires,則默認為會話關閉時間;

會話是瀏覽器的一個概念,一般是一個瀏覽器 Tab 窗口。

如果瀏覽器提供了會話恢復功能,恢復回話之時,Cookie 也會一起恢復,就好像會話從來沒有關閉一樣。

Max-Age

在 Cookie 失效之前需要經過的秒數。秒數為 0 或 -1 將會使 cookie 直接過期。一些老的瀏覽器(IE 6、IE 7 和 IE 8)不支持這個屬性。

如果 Expires?和Max-Age 同時存在時,Max-Age優先級更高。

HttpOnly

設置了 HttpOnly 屬性的 cookie 不能使用 JavaScript 經由 ?Document.cookie?屬性、XMLHttpRequest?和 ?Request?APIs、Cookie Store APIs 進行訪問。

bc05151902979621e571a0d74f5477be.png

Secure

標記為?Secure?的 Cookie 只應通過被 HTTPS 協議加密過的請求發送給服務端,因此可以預防 man-in-the-middle 攻擊。

但即便設置了?Secure?標記,敏感信息也不應該通過 Cookie 傳輸,因為 Cookie 固有的不安全性,Secure?標記也無法提供確實的安全保障,例如:可以訪問客戶端硬盤的人可以讀取它。

SameSite

服務器要求某個 Cookie 在跨站請求時不會被發送,從而可以阻止跨站請求偽造攻擊。

SameSite 可以有下面三種值:

  • **None**:瀏覽器會在同站請求、跨站請求下繼續發送 Cookies,不區分大小寫。

  • **Strict**:瀏覽器將只在訪問站點與 Cookie 生效的域相同時發送 Cookie。

  • **Lax**:新版本瀏覽器默認設置為 Lax。與?Strict?類似,但是特定條件也可以發送跨域請求:

    舉個例子,用戶從 a.com 跳轉到 b.com,URL 發生了變化的同時請求方式為 GET,所以 設置了 Lax的 Cookie 會被發送過去 ,除此之外還有圖片加載、iframe 調用等等。

    • URL 必須發生變化

    • HTTP 請求方式必須是安全的,例如 GETHEADOPTIONS,它們不改變數據。

SameSite 和 Domain 的區別

上面提到過,Domain 可以指定 Cookie 生效的域名,那它和 Domain的區別是什么呢?

Domain 屬性限制了接收 Cookie 的域名,而 SameSite屬性限制了發送 Cookie 的域名

舉個例子:

Set-Cookie: Foo=bar; Path=/; Secure; Domain=scar.site;

無論是從 scar.site 還是 foo.example.com 發起的請求,只要被發送到了 scar.site 或者它的子域名,那 Cookie 就能發過去。

Set-Cookie: name=scar; Path=/; Secure; Domain=scar.site;SameSite=strict;

如果設置了 SameSite=strict,那么這個請求只能從 scar.site 發起 Cookie 才能帶過去。

SameParty

目前還在實驗階段

配合 ?First-Party Sets 實現跨域共享屬性,詳細可以訪問:詳解 Cookie 新增的 SameParty 屬性。

Priority

目前只有 Chrome 實現了這個提案

因為 Cookie 有數量限制,所以在 Cookie 超過一定數量時,瀏覽器會清除最早過期的 Cookie。

如果設置了 Priority,Chrome 會先將優先級低的清除,并且每種優先級 Cookie 至少保留一個。可以有下面三種值:

  • Low:低優先級

  • Medium:默認值,中優先級

  • High:高優先級

Q&A

一些關于 Cookie 的疑問和新特性,以 Q&A 形式記錄。比較雜、比較散,可以說沒什么知識點全是感情,屬于那種你知道了可能沒什么用但是就是想把它弄懂。

1. Cookie 的限制

大小限制

大多數瀏覽器支持最大為 4KB 的 Cookie,4KB 是針對 Cookie 單條記錄的 Value 值。

數量限制

Cookie 有數量限制,而且只允許每個站點存儲一定數量的 Cookie,當超過時,最早過期的 Cookie 便被刪除。

不同瀏覽器支持的數量可能不同, 基于 Webkit 內核的是 180 個,基于 gecko 內核的是 150 個,感興趣可以訪問江濤學編程-編寫的 Cookie 實驗 試試自己的瀏覽器 Cookie 數量限制

實際上影響 Cookie 被刪除的要素不止是 ExpiresMax-Age,還有 PrioritySecure,對移除策略感興趣的可以看:Cookie 知識二則

2. 和 Cookie 相關的不安全事件有哪些?

CSRF 攻擊

CSRF:跨站請求攻擊,簡單地說,是攻擊者通過一些技術手段欺騙用戶的瀏覽器去訪問一個自己曾經認證過的網站并運行一些操作(如發郵件,發消息,甚至財產操作如轉賬和購買商品)。

舉個例子,一家銀行用以運行轉賬操作的 URL 如下:

http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName

那么,一個惡意攻擊者可以在另一個網站上放置如下代碼:

<img?src="<http://www.examplebank.com/withdraw?account=scar&amount=1000&for=Badman>">

如果有賬戶名為 Alice 的用戶訪問了惡意站點,而她之前剛訪問過銀行不久,登錄信息尚未過期,導致發起請求后后端以為是用戶正常操作,于是進行扣款操作,那么她就會損失 1000 資金。通過設置 sameSite 可以防止跨域發送 Cookie,抵御 CSRF。

XSS 攻擊

跨站腳本(Cross-site scripting)是一種網站應用程序的安全漏洞攻擊,簡稱為 CSS, 但這會與層疊樣式表(Cascading Style Sheets)CSS的縮寫混淆。因此,跨站腳本攻擊縮寫為 XSS。

XSS 攻擊通常指的是通過利用網頁開發時留下的漏洞,通過巧妙的方法注入惡意指令代碼到網頁,使用戶加載并執行攻擊者惡意制造的網頁程序。攻擊成功后,攻擊者可能得到 Cookie 從而實現攻擊。

3. Floc 替代第三方 Cookie?

引用自:如果不用第三方 Cookie,Google FLoC 會是更好的替代者嗎?- 少數派

FLoC 是一種新的廣告追蹤技術,全稱為 Federated Learning of Cohorts,即「同類群組聯合學習」。FLoC 的工作原理是監視你的瀏覽記錄,為訪客的匯總行為分配一個 ID,然后將具有類似瀏覽行為的瀏覽器分組在一起。這些群組的數據稱為同類群組,然后用于向人們展示針對性更強的廣告。

08d1649d949285a9c74b70450566858a.png

FLoC 在自身設計層面,是比 Cookie 隱私性更好的,但是首先它依然是一個廣告追蹤技術,其次才是一個相對保護隱私的廣告追蹤技術。

FLoC 由 Google 主導,所以三方團體擔憂:當所有的瀏覽器開始默認屏蔽第三方 Cookie,廣告商轉向使用 FLoC 以后,Google 將在廣告追蹤市場一家獨大。

4. 同名 Cookie 發送時,優先級如何判斷?

Cookie: a=2; a=1

首先來看看 Cookie 發送順序,RFC 6265提案提到:

  • Path 屬性較長的應該在前面

  • 如果 Path 路徑一樣,創建時間早的在前面

具體的瀏覽器表現我沒有去探究,但提案只是倡導,所以每個客戶端不一定會按照它實現 Cookie 的發送順序。

除了考慮發送順序,還要考慮不同的服務器框架可能有不同的接收邏輯,所以筆者推薦盡量避免出現同名 Cookie,減少端表現不統一帶來的不確定性。

5. 如何快速調試 Cookie

F12 打開控制臺可以快速看到本域下的所有 Cookie

e6e6797d33dde1eea2840d6c3946a56e.png

通過分析 Cookie 屬性來定位問題。

例如某個 Cookie 導致了業務問題,如果它設置了 HttpOnly,那么代表客戶端無法操作 Cookie,可以快速的把問題定位到 API 層面。

總結

本來我在寫:Cookie、Session、Token ,寫著寫著發現 Cookie 的篇幅比較多,而那篇文章的重點不在于這些部分,所以摘了出來。如果對 Cookie、Session、Token 感興趣的可以持續關注一下我,近期會發哦~

作為一名前端人員,平時用得少所以不熟悉,但了解后其實也沒有什么難點,相信你們看完這篇就可以徹底了解了。如果文章中還有關于 Cookie 你想知道但是我沒寫的部分都可以評論,我會回復。

參考資料

  • Cookies - mozilla

  • Set-Cookies - mozilla

  • Cookie 前綴如何讓 Cookie 更安全?- 阿里云社區

  • What is a Session Cookie?

  • View, edit, and delete cookies

  • Correct way to delete cookies server-side

  • Feature: Cookie Store API

  • 面試:徹底理解 Cookie 以及 Cookie 安全

  • 如果不用第三方 Cookie,Google FLoC 會是更好的替代者嗎?- 少數派

  • FLoC 是什么?以及你為什么需要在 Chrome 瀏覽器中禁用它 · Ruby China

  • 分享一個關于 Cookie 做的實驗結果 - ataola - 博客園

  • What are the security differences between cookies with Domain vs SameSite strict? - Stack Overflow

  • What is difference between SameSite="Lax" and SameSite="Strict"? - Stack Overflow

  • Cookie 知識二則

  • How to handle multiple cookies with the same name? - Stack Overflow



d6584f78ce1c5a6f9e4ca86467954daf.gif

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經堅持寫了8年,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助3000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。

2ed4f69dcfc41e63f3941cc4e938d801.png

掃碼加我微信 ruochuan02、拉你進源碼共讀

今日話題

目前建有江西|湖南|湖北?籍 前端群,想進群的可以加我微信 ruochuan12?進群分享、收藏、點贊、在看我的文章就是對我最大的支持~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/274752.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/274752.shtml
英文地址,請注明出處:http://en.pswp.cn/news/274752.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ui設計師常用的設計工具_2020年應該使用哪個UI設計工具?

ui設計師常用的設計工具重點 (Top highlight)It’s 2020, the market today is saturated with UI design tools. Ever since Sketch app came out with its sleek, simple, and efficient tool to craft user interface design, many companies have followed suit to take a …

Ajax拖放頁面元素(圖片)

最近了解了一點YUI的控件知識.先做個Ajax拖放頁面元素(圖片)以便學習參考. 現在有一些網站如QQ空間,都允許用戶自定義模塊,可以任意拖動模塊到各個地方去.YUI在這一方面做得比較好.下面以一組圖片的方式來說明如何運用Ajax拖放頁面元素: 第一步:在<head></head>標簽…

你不知道的vscode之空間控制

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列王志遠…

正則表達式說明

參考地址&#xff1a; 正則表達式說明 正則表達式全部符號解釋轉載于:https://www.cnblogs.com/s-bridge/archive/2012/06/26/2564396.html

lynda ux_UX心態

lynda uxI have had the pleasure of training and mentoring several UX people at the beginning of their careers.在職業生涯的初期&#xff0c;我很高興接受培訓和指導。 Whatever your background or experience, I’ve found repeatedly that there are some key miles…

什么 Leader 值得追隨?

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。目前建有江西|湖南|湖北 籍 前端群&#xff0c;想進群的可以加我微信 ruochuan12 進群。歷…

pico8 掌機_使用Pico-8構建自己的復古游戲

pico8 掌機An example of the kinds of pixel animations people make in Pico-8.人們在Pico-8中制作的各種像素動畫的示例。 Are you a fan of old school video games? What if I told you there’s an NES-style game devkit with the sound/sprite/code tools all built i…

C#中Brush、Color、String相互轉換

1、String轉換成Color Color color (Color)ColorConverter.ConvertFromString(string); 2、String轉換成Brush BrushConverter brushConverter new BrushConverter(); Brush brush (Brush)brushConverter.ConvertFromString(string); 3、Color轉換成Brush Brush …

實用 JavaScript 調試技巧

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

數據挖掘 點擊更多 界面_6(更多)技巧,可快速改善用戶界面

數據挖掘 點擊更多 界面重點 (Top highlight)Creating beautiful, usable, and efficient UIs takes time, with many design revisions along the way.創建漂亮&#xff0c;可用和高效的UI需要花費時間&#xff0c;并且在此過程中進行了許多設計修訂。 Making those constant…

簡單的ASP.NET無刷新分頁

1、新建一個分頁存儲過程&#xff1a; CREATE procedure [dbo].[P_Pager] (PageNumber int, PageSize int) as declare sql nvarchar(4000) set sql select top Convert(varchar, PageSize) * from T_Test where [type]1 and id not in (select top Convert(…

Koa在實際的業務場景中,路由如何做分割?【文末留言送書】

大家好&#xff0c;我是若川。文末留言送書&#xff0c;具體規則文末說明。另外為了鼓勵大家多寫源碼共讀筆記&#xff0c;我會在寫了5次及以上筆記的作者群里也抽獎送這本書。以后也會有更多福利傾斜。導讀&#xff1a;Koa是一個Node框架&#xff0c;在Node開源社區中&#xf…

設計模式_設計

設計模式Thanks for my colleague WanChing‘s help to prepare this sharing article. E-Commerce app collects plentiful products from various brands. Each brand has its brand signature colors and public image. This article introduces how we made a single page …

動態切換css

方法一&#xff1a;給link一個id&#xff0c;直接獲取該DOM操作href <link rel"stylesheet" id"stylelink" type"text/css"/> <a href"#" οnclickjavascript:document.getElementById("stylelink").href "…

使用 GTD 優化自己的工作和生活

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

模仿不再受寵若驚

If you haven’t heard of the Jio-Zoom plagiarism clash, you’re probably living under a rock (which may not be a bad idea given the state of the world right now). The turf war between Jio Meet and Zoom began when the Indian telecom giant ripped off the Chi…

一個計算機愛好者的不完整回憶(二十八)關于計算機書籍

我只在大學階段在圖書館看了很多計算機方面的書&#xff0c;無論已經老得都殘破了還是最新出版的。前兩天又看到論壇中有關于計算機書籍特別是國內人士編寫或翻譯的計算機書籍的評論的文章&#xff0c;譚浩強老先生又毫無懸念的被牽連了進來。也發表一下自己的一些觀點吧。   …

Vue2剝絲抽繭-響應式系統 系列

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

word文本樣式代碼樣式_使用文本樣式表達創建真相來源

word文本樣式代碼樣式As of After Effects 17.0, you can use expressions to edit text styles in After Effects. Here’s why this would transform your workflow:從After Effects 17.0開始&#xff0c;您可以使用表達式在After Effects中編輯文本樣式。 這就是這將改變您的…

mvn備忘

創建web工程 mvn archetype:generate -DgroupIdcom.malangmedia -DartifactIdautoDeployToJetty -DarchetypeArtifactIdmaven-archetype-webapp -Dversion1.0 添加jetty插件 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.or…