Lesen Sie diesen Artikel, Sie werden:
Ein paar super-praktische Antwort-Header lernen, um die Probleme zu lösen, auf die Sie bei der Arbeit stoßen.
löst nicht nur das Problem, sondern verschafft Ihnen auch die Oberhand , wenn Sie mit dem Backend sowie Betrieb und Wartung uneins sind.
Ist es wichtig, Antwortheader zu lernen?
Es ist wirklich wichtig.
Wenn Sie mir nicht glauben, schauen Sie sich die Szene unten an. Kommt sie Ihnen bekannt vor? 1. Sind Vorschauen und Downloads frustrierend? oder
pdf
/'json' usw.) Datei-Download
url
kann geöffnet werden, wenn ich das
a
-Tag verwende, aber es wird eine Vorschau. .. Was soll ich tun? Speichern! „
Zu diesem Zeitpunkt wird jemand FileSaver.js
oder „Handgeschriebenen Lesestream speichern unter“ empfehlen. Dann wiederholte jemand anderes...
Ich:? ? ?
Ist das ein Problem, für dessen Lösung das Schreiben von Code erforderlich ist?
Wenn Sie den
Response Header
von
Content-Disposition
kennen, müssen Sie wissen, dass das Problem durch einfaches Hinzufügen einer Zeile zum Antwortheader gelöst werden kann.
1.2 Einführungtxt
(或者 pdf
/'json' 等)文件的下载 url
,可以当我用 a
标签打开时,却变成了预览……怎么办?救!!!”
此时,就会有人上去推荐 FileSaver.js
或者 “手写读流另存为”。
然后还有人附和...
我:???
这是需要写代码才能解决的问题吗?
如果你有了解过 Content-Disposition
这个 Response Header
,那你一定知道,只需要响应头上增加一行,问题就能迎刃而解。
1.2 介绍
Content-Disposition
:这个响应头可以决定内容是 预览 还是 下载。
它支持三种格式的值:
Content-Disposition: inline
此时,消息体会以页面的一部分或者整个页面的形式展示。(预览)
Content-Disposition: attachment
消息体应该被下载,默认文件名和 url
格式有关。
Content-Disposition: attachment; filename="filename.jpg"
消息体应该被下载,默认文件名可指定。
注:如果需要预览,需要配合适当的 Content-Type
食用;
1.3 示例
为此,我特意写了一个 express
小示例。
大抵是在 express
应用下写了三个路由,如下:
const user = {
name: "摸鱼的春哥",
blogUrl: "https://juejin.cn/user/1714893870865303"
}
const contentDispositionInline = async (req, res, next) => {
res.setHeader('Content-Disposition', 'inline')
res.send(user)
}
const contentDispositionFilename = async (req, res, next) => {
res.setHeader('Content-Disposition', 'attachment; filename="chunge.json"')
res.send(user)
}
const contentDispositionNoFilename = async (req, res, next) => {
res.setHeader('Content-Disposition', 'attachment')
res.send(user)
}
然后我分别访问三个路由,效果差异:
二、项目升级了,需要客户 清空缓存 ?
2.1 场景
实施:“客户反馈Bug
还是没修复。”
你:“哥,真修复了,要不你让客户清一下缓存?”
实施:“啊?客户说他不会清……”
……
永远不要期望你的客户会进行 “那些研发才懂” 的操作。也不要把你的问题,归因到 浏览器缓存 上。
浏览器缓存 是被发明出来优化用户体验的,并不是被发明出来阻碍用户的。
因此,理解如何使用 Cache-Control
这个响应头,是前端的必知技能。
2.2 介绍
Cache-Control
:用来指定缓存机制。
缓存,作为前端八股文必考知识,相信大家已经耳熟能详。
常见的 Cache-Control
🎜
Content-Disposition
🎜: Dieser Antwortheader kann bestimmen, ob der Inhalt 🎜Vorschau🎜 oder 🎜Download🎜 ist. 🎜🎜Es unterstützt drei Werteformate: 🎜🎜🎜🎜
Content-Disposition: inline
Zu diesem Zeitpunkt wird der Nachrichtentext als Teil der Seite oder als gesamte Seite angezeigt. (Vorschau) 🎜🎜🎜🎜
Content-Disposition: Anhang
Der Nachrichtentext sollte heruntergeladen werden und der Standarddateiname bezieht sich auf das
URL
-Format. 🎜🎜🎜🎜
Content-Disposition: attachment; filename="filename.jpg"
Der Nachrichtentext sollte heruntergeladen werden und der Standarddateiname kann angegeben werden. 🎜🎜🎜🎜🎜Hinweis: Wenn Sie eine Vorschau benötigen, müssen Sie diese mit dem entsprechenden
Content-Type
abgleichen 🎜🎜
🎜1.3 Beispiel 🎜 🎜🎜Dafür habe ich speziell ein kleines Beispiel für express
geschrieben. 🎜🎜Ich habe wahrscheinlich drei Routen unter der express
-Anwendung geschrieben, wie folgt: 🎜rrreee🎜Dann habe ich jeweils auf die drei Routen zugegriffen und der Effekt war unterschiedlich: 🎜🎜🎜🎜 II. Das Projekt wurde aktualisiert und der Kunde muss den Cache leeren? 🎜🎜🎜2.1 Szenario 🎜🎜🎜Implementierung: „Kundenfeedback Bug
ist immer noch nicht behoben.“
Sie: „Bruder, das ist es wirklich behoben. Wie wäre es, wenn Sie den Kunden bitten würden, den Cache zu leeren? ://img.php.cn/ " alt="" Loading="lazy" class="medium-zoom-image"/>🎜🎜Erwarten Sie von Ihren Kunden niemals, dass sie 🎜„Forschung und Entwicklung verstehen nur“-Operationen🎜 ausführen. Führen Sie Ihr Problem auch nicht auf den 🎜Browser-Cache🎜 zurück. 🎜🎜🎜Browser-Cache🎜 wurde erfunden, um die Benutzererfahrung zu optimieren und nicht, um Benutzer zu behindern. 🎜🎜Daher ist das Verständnis der Verwendung des Cache-Control
-Antwortheaders eine unverzichtbare Fähigkeit für das Frontend. 🎜🎜2.2 Einführung🎜🎜🎜🎜Cache-Control
🎜: Wird zur Angabe des Caching-Mechanismus verwendet. 🎜🎜Caching ist ein Muss für achtteilige Front-End-Aufsätze und meiner Meinung nach ist es jedem bekannt.
Allgemeine 🎜Cache-Control
🎜-Attribute sind wie folgt: 🎜„Antwort-Header-Attribut“ Wert „Wert“ genannt starker Cache , Cache aushandeln.
cache-control |
public |
gibt an, dass die Antwort von jedem zwischengespeichert werden kann (einschließlich: dem Client, der die Anfrage stellt, dem Proxyserver usw.), selbst für normalerweise nicht zwischenspeicherbare Inhalte. (Zum Beispiel: 1. Die Antwort verfügt nicht über eine Max-Age-Anweisung oder einen Expires-Header; 2. Die dieser Antwort entsprechende Anforderungsmethode ist POST.) |
cache-control
private |
gibt an, dass die Antwort dies kann kann nur von einem einzelnen Benutzer zwischengespeichert werden. Kann nicht als Freigabe zwischengespeichert werden (d. h. der Proxyserver kann sie nicht zwischenspeichern). Ein privater Cache kann beispielsweise Antwortinhalte entsprechend dem lokalen Browser des Benutzers zwischenspeichern. |
|
cache-control
max-age= |
Legen Sie die maximale Cache-Speicherdauer fest, ab der der Cache als abgelaufen gilt (in Sekunden). Im Gegensatz zu Expires ist die Zeit relativ zum Zeitpunkt der Anfrage. |
|
- Kein Caching
Kein Caching ist am einfachsten zu verstehen. Jede Anfrage wird ohne Caching erneut vom Server abgerufen.
Dieser Strategie muss nur der Antwortheader Cache-Control: no-store
gegeben werden.
Cache-Control: no-store
响应头即可。- 强缓存
有些资源文件,几乎不会发生变化(比如已经 hash化命名的文件
),则可以直接从本地缓存获取,这就是所谓的 强缓存 ;
通过 cache-control: public/private
或者 cache-control: max-age=
都可以指定机制为强缓存。
- 协商缓存
这是一种更为复杂缓存机制,无法再通过响应头 简单粗暴地 指定实现,而是需要前后端协作配合。
简单来说,每次请求资源前前端会写代前一次的响应 hash
,问询服务端 资源是否发生过变化,从而达到准确缓存的效果。
本文不赘述,如果有兴趣,可以参考此文:juejin.cn/post/703078…
2.3 实际生产如何运用?
- 凡是名称带有
hash
值的资源,一律可以强缓存。
(毕竟内容一旦有变化,名称的hash
也跟着变了)
- 凡是通过
cdn
引入的第三方库,均建议携带版本信息,这样也可以强缓存。
(比如 /xx/xx/jquery.min.js
切换为 jquery@3.6.0/dist/jquery.min.js
)
- 凡是
html
、ico
这类命名固定的文件,建议一律 不缓存 或者 协商缓存。
三、我的 Cookie
不可能这么可爱!
3.1 场景
"春哥春哥,为啥我登录成功了,请求还是 401
?"
"春哥春哥,为啥我存进 cookie
的值取不到?"
"春哥春哥,这破 cookie
是不是坏了,浏览器里看明明有值,为啥我访问不了?"
我:“兄弟,你有了解过一个叫 set-cookie
的响应头吗?”
是它!是它!就是它!关于 cookie
的各种异常,全靠它!
3.2 介绍
Cookie
曾经是 Web
开发无法绕开的一道门槛,而现在它的存在感越来越弱,但海量的存量项目并不会因为技术的趋势而消失,它们依然很有价值,依然需要维护。
而 set-cookie
响应头正是 Cookie
体系中最为核心的 第一主角。
Set-Cookie
: 是一个响应头,服务端赋值,让浏览器端产生 Cookie
,并限定 Cookie
Starkes Caching
Einige Ressourcendateien ändern sich kaum (z. B. Dateien mit Hash-Namen
) und können direkt aus dem lokalen Cache abgerufen werden Starkes Caching ;Sie können den Mechanismus als starkes Caching über cache-control: public/private
oder cache-control: max-age= angeben.
.
Negotiation Caching🎜Dies ist ein komplexerer Caching-Mechanismus. Die Implementierung kann nicht mehr einfach und grob über den Antwortheader angegeben werden, sondern erfordert die Zusammenarbeit von Front-End und Back-End . 🎜Um es einfach auszudrücken: Vor jeder Anfrage nach einer Ressource schreibt das Front-End den Hash
der vorherigen Antwort und fragt den Server, ob sich die Ressource geändert hat, um dies zu tun Erzielen Sie einen genauen Caching-Effekt. 🎜Ich werde in diesem Artikel nicht auf Details eingehen. Wenn Sie interessiert sind, können Sie auf diesen Artikel verweisen: juejin .cn/post/703078…2.3 Wie man es anwendet tatsächliche Produktion?
🎜🎜Jede Ressource, deren Name einen Hash
-Wert enthält, kann stark zwischengespeichert werden. 🎜(Schließlich ändert sich auch der Hash
des Namens, sobald sich der Inhalt ändert.)🎜Es wird empfohlen, jede über cdn
eingeführte Bibliothek eines Drittanbieters zu übertragen Dies ermöglicht auch ein starkes Caching. 🎜(Zum Beispiel wechselt /xx/xx/jquery.min.js
zu jquery@3.6.0/dist/jquery.min.js
)🎜 Beliebig html und ico
wird empfohlen, nicht zwischenzuspeichern oder den Cache auszuhandeln. 3 Mein Cookie
kann nicht so süß sein!
3.1 Szenario
🎜"Bruder Chun, Bruder Chun, warum habe ich mich erfolgreich angemeldet? ? Die Anfrage lautet immer noch 401
? 🎜"Bruder Chun, Bruder Chun, ist dieses Cookie
kaputt? Es ist eindeutig wertvoll im Browser, warum kann ich nicht darauf zugreifen?"🎜
🎜Ich: „Bruder , haben Sie schon einmal von einem Antwortheader namens set-cookie
gehört? /upload/image/177/689/695/1663124856730779.png" title="1663124856730779.png" alt="[Zusammenstellung und Zusammenfassung] Mehrere praktische Antwortheader, die das Front-End kennen muss"/>🎜🎜Das ist es! Das ist es! Das ist es! Alle Arten von Ausnahmen zu cookie
hängen davon ab!🎜3.2 Einführung
🎜Cookie Code> war früher eine Schwelle, die in der <code>Web
-Entwicklung nicht umgangen werden konnte, aber jetzt wird seine Präsenz immer schwächer, aber die massiven Aktienprojekte werden aufgrund technologischer Trends nicht verschwinden, sie sind immer noch sehr vorhanden wichtig Es hat einen Wert, muss aber dennoch gewartet werden. 🎜🎜Der set-cookie
-Antwortheader ist der zentrale erste Protagonist im Cookie
-System. 🎜🎜Set-Cookie
: Es handelt sich um einen vom Server zugewiesenen Antwortheader, der es dem Browser ermöglicht, Cookie
zu generieren und Cookie einzuschränken <verschiedene funktionen von>. 🎜🎜Zu diesen Funktionen gehören:🎜<ul>
<li>Ablaufzeitlimit; <code>Expires=<date></date>
Expires=<date></date>
存活周期;Max-Age=<number></number>
在 cookie 失效之前需要经过的秒数。0
或 -1
直接失效;此属性的优先级高于 Expires
。
域名;Domain=<domain-value></domain-value>
指定 cookie
只能在什么域下生成;(允许通配,这个属性主要出于安全性)
路径;Path=<path-value></path-value>
比 Domain
更为细致的控制策略,甚至指定了 xx
路径下才能发送 Cookie
。
只在 Https
产生;Secure
如果 set-cookie
头中有 Secure
属性,那么浏览器只会在 Https
环境产生和发送 Cookie
。
禁用 js
操作 API
;HttpOnly
如果 set-cookie
头中有 HttpOnly
属性,那么 Cookie
属性的生成、读写、发送就只能由浏览器通过 "响应头" 控制了,不在允许前端通过 js
操作 Cookie
。
是否允许跨域携带;SameSite=<samesite-value></samesite-value>
支持属性包括 Strict
、Lax
、None
,分别表示:
-
Strict
: 完全不能跨域携带;
-
Lax
: 只允许从外站导航到源站时携带 Cookie
-
None
:跨域也行,不限制。
3.3 开发常见问题分析
-
为啥你登录成功了,请求还是 401
?
早期非常多的项目,使用 Cookie
作为用户身份识别的手段,比如 Spring MVC
项目就是通过给 Cookie
一个 JSeesionId
的值作为识别,判断你是否出于当前会话。
而 "登录了,却还 401
" 这个现象,如果服务端没有问题的话,多半是 浏览器其实并未存储Cookie。
换个说法,你每次发起请求,服务端都认为你是一次 新的会话,和上一次 登录的你 并非同一人。
如果你正处于 http
环境,那你可能需要暂时移除 Secure
属性。
存不进、取不出?
先确认 是否有域的限制、是否有路径的限制、是否有 HttpOnly
Lifetime; Max-Age=<number></number>
Die Anzahl der Sekunden, die bis zum Cookie vergehen müssen läuft ab. 0
oder -1
schlägt direkt fehl; dieses Attribut hat eine höhere Priorität als Expires
.
Domänenname; Domain=<domain-value></domain-value>
Geben Sie die Domäne an, in der nur Cookie
generiert werden kann; dieses Attribut dient hauptsächlich der Sicherheit ) Path; Path=<path-value></path-value>
Detailliertere Kontrollstrategie als Domain
, sogar Angabe des xx
-Pfads zum Senden Cookie
. 🎜Nur in Https
generiert; Secure
🎜Wenn das Attribut Secure
im Header set-cookie
vorhanden ist, dann Das Browser-Cookie
wird nur in der Https
-Umgebung generiert und gesendet. 🎜🎜Deaktivieren Sie die js
-Operation API
; HttpOnly
🎜Wenn HttpOnly
im set-cookie Header-Code>-Attribut, dann kann das Generieren, Lesen, Schreiben und Senden des <code>Cookie
-Attributs nur noch vom Browser über den „Antwortheader“ gesteuert werden, das Frontend jedoch nicht mehr erlaubt, js
>Cookie zu betreiben. 🎜🎜Ob domänenübergreifende Portabilität zulässig ist; SameSite=<samesite-value></samesite-value>
🎜Zu den unterstützten Attributen gehören Strict
, Lax
, Keine bzw.: 🎜🎜<code>Streng
: kann überhaupt nicht über Domänen übertragen werden 🎜🎜Lax
: erlaubt nur die Übertragung von Cookies beim Navigieren von eine externe Site zur Ursprungssite
🎜🎜Keine
: Cross-Domain ist ebenfalls akzeptabel, keine Einschränkungen. 🎜🎜🎜🎜3.3 Analyse der Entwicklungs-FAQs🎜
🎜🎜🎜Warum ist die Anfrage immer noch 401
, nachdem Sie sich erfolgreich angemeldet haben? ? 🎜🎜Viele frühe Projekte verwendeten Cookie
als Mittel zur Benutzeridentifizierung. Beispielsweise gab das Spring MVC
-Projekt Cookie
einen -Wert von JSeesionId
wird als Identifikation verwendet, um festzustellen, ob Sie sich in der aktuellen Sitzung befinden. 🎜🎜Was das Phänomen „Angemeldet, aber immer noch 401
“ betrifft: Wenn auf der Serverseite kein Problem vorliegt, liegt das wahrscheinlich daran, dass der Browser eigentlich keine Cookies speichert🎜. 🎜🎜Mit anderen Worten: Jedes Mal, wenn Sie eine Anfrage stellen, geht der Server davon aus, dass Sie sich in einer neuen Sitzung befinden🎜 und dass Sie nicht dieselbe Person sind wie bei der letzten Anmeldung🎜. 🎜🎜Wenn Sie sich in einer http
-Umgebung befinden, müssen Sie möglicherweise vorübergehend das Attribut Secure
entfernen. 🎜🎜🎜🎜Kann ich nicht einzahlen oder abheben? 🎜Bestätigen Sie zunächst, ob es Domänenbeschränkungen gibt🎜, ob es Pfadbeschränkungen gibt🎜, ob es HttpOnly
gibt🎜?🎜Überprüfen Sie sie einzeln, und das Problem wird behoben nicht schwer zu lösen sein. 🎜🎜🎜🎜 (Lernvideo-Sharing: 🎜Web-Frontend🎜)🎜
Das obige ist der detaillierte Inhalt von[Zusammenstellung und Zusammenfassung] Mehrere praktische Antwortheader, die das Front-End kennen muss. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!