Maison >interface Web >js tutoriel >[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître

[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître

青灯夜游
青灯夜游avant
2022-09-14 11:11:542881parcourir

[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître

Lisez cet article, vous allez :

  • Apprendre quelques En-têtes de réponse super et super pratiques pour résoudre les problèmes que vous rencontrez au travail.

  • non seulement résout le problème, mais vous donne également le dessus lorsque vous êtes en désaccord avec le backend, l'exploitation et la maintenance.

Est-il important d'apprendre les en-têtes de réponse ?

C’est vraiment important.

Si vous ne me croyez pas, jetez un œil à la scène ci-dessous, est-ce qu'elle vous semble familière ?

1. Les aperçus et les téléchargements sont-ils frustrants ?

1.1 Scénario

J'ai entendu des collègues et des amis du groupe discuter de ce problème plus d'une fois :

"Le backend fournit un txt ( ou pdf/'json', etc.) le téléchargement de fichiers url peut être ouvert lorsque j'utilise la balise a, mais cela devient un aperçu. .. Que dois-je faire ? Enregistrer ! "

txt(或者 pdf/'json' 等)文件的下载 url,可以当我用 a 标签打开时,却变成了预览……怎么办?救!!!”

此时,就会有人上去推荐 FileSaver.js 或者 “手写读流另存为”。

然后还有人附和...

我:???

[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître

这是需要写代码才能解决的问题吗?

如果你有了解过 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)
}

然后我分别访问三个路由,效果差异:

[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître

二、项目升级了,需要客户 清空缓存 ?

2.1 场景

实施:“客户反馈Bug 还是没修复。”
你:“哥,真修复了,要不你让客户清一下缓存?”
实施:“啊?客户说他不会清……”
……

永远不要期望你的客户会进行 “那些研发才懂” 的操作。也不要把你的问题,归因到 浏览器缓存 上。

浏览器缓存 是被发明出来优化用户体验的,并不是被发明出来阻碍用户的。

因此,理解如何使用 Cache-Control 这个响应头,是前端的必知技能。

2.2 介绍

Cache-Control:用来指定缓存机制。

缓存,作为前端八股文必考知识,相信大家已经耳熟能详。 常见的 Cache-ControlÀ ce moment-là, quelqu'un viendra et recommandera FileSaver.js ou "Enregistrer le flux de lecture manuscrit sous".

🎜Puis quelqu'un d'autre a fait écho...🎜🎜Moi : ? ? ? 🎜

[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître🎜🎜Est-ce un problème qui nécessite l'écriture de code pour être résolu ? 🎜🎜Si vous connaissez le Response Header de Content-Disposition, alors vous devez savoir que le problème peut être résolu en ajoutant simplement une ligne à l'en-tête de réponse. 🎜

🎜1.2 Introduction🎜🎜🎜🎜Content-Disposition🎜 : Cet en-tête de réponse peut déterminer si le contenu est 🎜aperçu🎜 ou 🎜téléchargement🎜. 🎜🎜Il prend en charge trois formats de valeurs : 🎜🎜🎜🎜Content-Disposition : inline
À ce stade, le corps du message sera affiché dans le cadre de la page ou de la page entière. (Aperçu) 🎜🎜🎜🎜Content-Disposition : pièce jointe
Le corps du message doit être téléchargé et le nom de fichier par défaut est lié au format url. 🎜🎜🎜🎜Content-Disposition : attachment; filename="filename.jpg"
Le corps du message doit être téléchargé et le nom de fichier par défaut peut être spécifié. 🎜🎜🎜🎜🎜Remarque : Si vous avez besoin d'un aperçu, vous devez utiliser le Content-Type approprié 🎜🎜

🎜1.3 Exemple 🎜🎜🎜 ; Pour cela, j'ai spécialement écrit un petit exemple de express. 🎜🎜J'ai probablement écrit trois itinéraires sous l'application express, comme suit : 🎜rrreee🎜Ensuite, j'ai accédé aux trois itinéraires respectivement, et l'effet était différent : 🎜🎜[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître🎜

🎜 2. Le projet a été mis à niveau et le client doit vider le cache ? 🎜🎜

🎜2.1 Scénario 🎜🎜🎜Mise en œuvre : "Les commentaires des clients Bug ne sont toujours pas corrigés."
Vous : "Frère, c'est vraiment corrigé. , pourquoi ne demandez-vous pas au client de vider le cache ?"
Mise en œuvre : "Hein ? Le client a dit qu'il ne pouvait pas le vider..."
...🎜🎜Ne vous attendez jamais à ce que vos clients effectuent des opérations 🎜"la recherche et le développement ne comprennent que"🎜 . N’attribuez pas non plus votre problème au 🎜cache du navigateur🎜. 🎜🎜🎜Le cache du navigateur🎜 a été inventé pour optimiser l'expérience utilisateur, et non pour gêner les utilisateurs. 🎜🎜Par conséquent, comprendre comment utiliser l'en-tête de réponse Cache-Control est une compétence incontournable pour le front-end. 🎜

🎜2.2 Introduction🎜🎜🎜🎜Cache-Control🎜 : Utilisé pour spécifier le mécanisme de mise en cache. 🎜🎜La mise en cache, en tant que connaissance incontournable pour les essais front-end en huit parties, je pense que tout le monde la connaît. Les attributs courants de 🎜Cache-Control🎜 sont les suivants : 🎜

Attribut d'en-tête de réponse valeur signification
cache-control no-store Pas de mise en cache, cela n'entraînera ni le client ni le serveur à mettre en cache, et il n'y a pas de so- Appelé cache fort , Négocier le cache.
cache-control public indique que la réponse peut être mise en cache par n'importe qui (y compris : le client faisant la demande, le serveur proxy, etc.), même pour un contenu normalement impossible à mettre en cache. (Par exemple : 1. Cette réponse n'a pas de directive max-age ni d'en-tête Expires ; 2. La méthode de requête correspondant à cette réponse est POST.)
cache-control private indique que la réponse peut ne peut être mis en cache que par un seul utilisateur, ne peut pas être mis en cache en tant que partage (c'est-à-dire que les serveurs proxy ne peuvent pas le mettre en cache). Un cache privé peut mettre en cache le contenu de la réponse, par exemple, correspondant au navigateur local de l'utilisateur.
cache-control max-age= Définissez la période maximale de stockage du cache, au-delà de laquelle le cache est considéré comme expiré (en secondes). Contrairement à Expires, l'heure est relative à l'heure de la demande.
  • Pas de mise en cache
    Pas de mise en cache est la solution la plus simple à comprendre. Chaque requête sera réobtenue du serveur sans aucune mise en cache.
    Cette stratégie doit uniquement recevoir l'en-tête de réponse Cache-Control: no-store.
  • 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
  • 凡是 htmlico 这类命名固定的文件,建议一律 不缓存 或者 协商缓存

三、我的 Cookie 不可能这么可爱!

3.1 场景

"春哥春哥,为啥我登录成功了,请求还是 401 ?"

"春哥春哥,为啥我存进 cookie 的值取不到?"

"春哥春哥,这破 cookie 是不是坏了,浏览器里看明明有值,为啥我访问不了?"

我:“兄弟,你有了解过一个叫 set-cookie 的响应头吗?”

[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître

是它!是它!就是它!关于 cookie 的各种异常,全靠它!

3.2 介绍

Cookie 曾经是 Web 开发无法绕开的一道门槛,而现在它的存在感越来越弱,但海量的存量项目并不会因为技术的趋势而消失,它们依然很有价值,依然需要维护。

set-cookie 响应头正是 Cookie 体系中最为核心的 第一主角

Set-Cookie: 是一个响应头,服务端赋值,让浏览器端产生 Cookie,并限定 CookieMise en cache puissante

Certains fichiers de ressources ne changeront presque jamais (comme les fichiers qui ont été nommés par hachage), qui peuvent être obtenus directement à partir du cache local. Mise en cache forte ;

Vous pouvez spécifier le mécanisme comme mise en cache forte via cache-control: public/private ou cache-control: max-age= .

Mise en cache de négociation🎜Il s'agit d'un mécanisme de mise en cache plus complexe. L'implémentation ne peut plus être simplement et grossièrement spécifiée via l'en-tête de réponse, mais nécessite une collaboration front-end et back-end. 🎜Pour faire simple, avant chaque requête de ressource, le front-end écrira la réponse précédente hash et demandera au serveur si la ressource a changé, afin de obtenir un effet de mise en cache précis. 🎜Je n'entrerai pas dans les détails dans cet article. Si vous êtes intéressé, vous pouvez vous référer à cet article : juejin .cn/post/703078…

2.3 Comment l'appliquer dans la production réelle ?

🎜🎜Toute ressource dont le nom contient une valeur hash peut être fortement mise en cache. 🎜(Après tout, une fois le contenu modifié, le hash du nom changera également)🎜Il est recommandé à toute bibliothèque tierce introduite via cdn d'emporter informations de version. Cela permet également une mise en cache renforcée. 🎜(Par exemple, /xx/xx/jquery.min.js passe à jquery@3.6.0/dist/jquery.min.js)🎜 Tout html et ico, il est recommandé de ne pas mettre en cache ou de négocier le cache.

3. Mon Cookie ne peut pas être si mignon !

Scénario 3.1

🎜"Frère Chun, frère Chun, pourquoi me suis-je connecté avec succès ? La requête est toujours 401 ? "🎜
🎜"Frère Chun, pourquoi ne puis-je pas obtenir la valeur que j'ai enregistrée dans le cookie ?
🎜"Frère Chun, Frère Chun, ce cookie est-il cassé ? Il a clairement de la valeur dans le navigateur, pourquoi ne puis-je pas y accéder ?"🎜
🎜Moi : "Frère , avez-vous déjà entendu parler d'un en-tête de réponse appelé set-cookie ?" 🎜

[Compilation et Résumé] Plusieurs en-têtes de réponse pratiques que le front-end doit connaître🎜🎜C'est tout ! C'est ça! C'est ça! Toutes sortes d'exceptions concernant les cookies en dépendent !🎜

3.2 Introduction

🎜Cookie était autrefois un seuil qui ne pouvait être contourné dans le développement <code>Web, mais maintenant sa présence devient de plus en plus faible, mais les projets de stock massifs ne disparaîtront pas à cause des tendances technologiques, ils sont encore très important Il a de la valeur, mais a encore besoin d'entretien. 🎜🎜L'en-tête de réponse set-cookie est le principal premier protagoniste du système Cookie. 🎜🎜Set-Cookie : Il s'agit d'un en-tête de réponse, attribué par le serveur, permettant au navigateur de générer des Cookie et de limiter les Cookie <diverses fonctionnalit de>. 🎜🎜Ces fonctionnalités incluent :🎜<ul> <li>Délai d'expiration ; <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 操作 APIHttpOnly
    如果 set-cookie 头中有 HttpOnly 属性,那么 Cookie 属性的生成、读写、发送就只能由浏览器通过 "响应头" 控制了,不在允许前端通过 js 操作 Cookie
  • 是否允许跨域携带;SameSite=<samesite-value></samesite-value>
    支持属性包括 StrictLaxNone,分别表示:
    • Strict: 完全不能跨域携带;
    • Lax: 只允许从外站导航到源站时携带 Cookie
    • None:跨域也行,不限制。
  • 3.3 开发常见问题分析

    • 为啥你登录成功了,请求还是 401

      早期非常多的项目,使用 Cookie 作为用户身份识别的手段,比如 Spring MVC 项目就是通过给 Cookie 一个 JSeesionId 的值作为识别,判断你是否出于当前会话。

      而 "登录了,却还 401" 这个现象,如果服务端没有问题的话,多半是 浏览器其实并未存储Cookie

      换个说法,你每次发起请求,服务端都认为你是一次 新的会话,和上一次 登录的你 并非同一人。

      如果你正处于 http 环境,那你可能需要暂时移除 Secure 属性。

    • 存不进、取不出?
      先确认 是否有域的限制是否有路径的限制是否有 HttpOnlyDurée de vie ; Max-Age=<number></number>
      Le nombre de secondes qui doivent s'écouler avant le cookie. expire. 0 ou -1 est directement invalide ; cet attribut a une priorité plus élevée que Expires.

    • Nom de domaine ; Domain=<domain-value></domain-value>
    Spécifiez le domaine dans lequel le cookie peut uniquement être généré (les caractères génériques sont autorisés, cet attribut est principalement destiné à la sécurité ; )

    Path; Path=<path-value></path-value>Stratégie de contrôle plus détaillée que Domain, spécifiant même le chemin xx pour envoyer Cookie

    . 🎜Généré uniquement dans Https ; Secure🎜S'il y a un attribut Secure dans l'en-tête set-cookie, alors le Cookie du navigateur sera généré et envoyé uniquement dans l'environnement Https. 🎜🎜Désactivez les opérations js API ; HttpOnly🎜S'il y a HttpOnly dans le set-cookie header code>, alors la génération, la lecture, l'écriture et l'envoi de l'attribut <code>Cookie ne peuvent être contrôlés que par le navigateur via "l'en-tête de réponse", et le front-end n'est plus autorisé à utiliser js >Cookie. 🎜🎜Si la portabilité entre domaines est autorisée ; SameSite=<samesite-value></samesite-value>🎜Les attributs pris en charge incluent Strict, Lax, . Aucun, respectivement : 🎜🎜<code>Strict : ne peut pas du tout être transporté entre les domaines ; 🎜🎜Lax : autorise uniquement le transport de Cookies lors de la navigation à partir de un site externe au site d'origine 🎜🎜Aucun : Le cross-domain est également acceptable, aucune restriction. 🎜🎜🎜🎜

    3.3 FAQ sur l'analyse du développement🎜

    🎜🎜🎜Pourquoi la demande est-elle toujours 401 après une connexion réussie ? 🎜🎜De nombreux premiers projets utilisaient Cookie comme moyen d'identification de l'utilisateur. Par exemple, le projet Spring MVC a donné à Cookie une valeur . de JSeesionId est utilisé comme identification pour déterminer si vous êtes dans la session en cours. 🎜🎜Quant au phénomène du "connecté, mais toujours 401", s'il n'y a pas de problème côté serveur, c'est probablement parce que le navigateur ne stocke pas réellement de cookies🎜. 🎜🎜En d'autres termes, à chaque fois que vous faites une demande, le serveur pense que vous êtes une nouvelle session🎜, et que vous n'êtes pas la même personne que la dernière fois que vous vous êtes connecté🎜. 🎜🎜Si vous êtes dans un environnement http, vous devrez peut-être supprimer temporairement l'attribut Secure. 🎜🎜🎜🎜Vous ne pouvez pas déposer ou retirer ? 🎜Confirmez d'abord s'il y a des restrictions de domaine🎜, s'il y a des restrictions de chemin🎜, s'il y a des HttpOnly🎜 ?🎜Vérifiez-les un par un, et le problème sera résolu. pas difficile à résoudre. 🎜🎜🎜🎜 (Partage de vidéos d'apprentissage : 🎜front-end web🎜)🎜

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer