|
2. Quels sont les principaux composants d'un navigateur ?
Interface utilisateur : comprend la barre d'adresse, les boutons avant/arrière/actualisation/signet et autres boutons
Moteur de navigateur : transmet les instructions entre l'interface utilisateur et le moteur de rendu
-
Moteur de rendu : utilisé pour dessiner les requêtes Contenu
Réseau : utilisé pour effectuer des appels réseau, tels que des requêtes http, il possède une interface indépendante de la plate-forme et peut fonctionner sur différentes plates-formes
Interpréteur JavaScript : utilisé pour analyser et exécuter du code JavaScript
Interface utilisateur Backend : Utilisé pour dessiner des widgets de base, tels que des zones de liste déroulante et des fenêtres. La couche inférieure utilise l'interface utilisateur du système d'exploitation
Stockage des données : Elle appartient à la couche de persistance. , HTML5 Définit la technologie de base de données Web, qui est une technologie de stockage légère et complète côté client
Remarque : contrairement à la plupart des navigateurs, chaque onglet du navigateur Google (Chrome) correspond chacun à une instance du moteur de rendu. Chaque onglet est un processus indépendant
3. Dites-moi ce qui se passe entre la saisie de l'URL et le rendu de la page ?
Cette question peut être considérée comme la question la plus courante lors des entretiens et peut être infiniment difficile. Généralement, les intervieweurs posent cette question pour tester la profondeur de vos connaissances frontales.
1. Le navigateur accepte l'URL et ouvre le fil de requête réseau (impliquant : le mécanisme du navigateur, le fil et le processus, etc.)
2 Ouvre le fil de discussion réseau et émet une requête http complète (impliquant : requête DNS, TCP. /IP, protocole réseau 5 couches, etc.)
3. Recevoir la requête du serveur vers le backend correspondant pour recevoir la requête (impliquant : l'équilibrage de charge, l'interception de sécurité, le traitement interne du backend, etc.)
4. . Interaction HTTP entre le backend et le frontend (impliquant To : en-têtes http, codes de réponse, structures de messages, cookies, etc.)
5. Problèmes de cache (impliquant : cache http fort et cache négocié, en-têtes de cache, etag, expiré, cache-control, etc.)
6. Navigateur Le processus d'analyse après la réception du paquet de données http (impliquant une analyse lexicale HTML, une analyse dans une arborescence DOM, une analyse CSS pour générer une arborescence CSSOM et une fusion pour générer une arborescence de rendu. Ensuite mise en page, rendu de peinture, synthèse de couches composites, dessin GPU, traitement des liens externes, etc.)
7 modèle visuel css (impliquant : règles de rendu des éléments, telles que : bloc contenant, boîte de contrôle, BFC, IFC, etc.)
. 8. Processus d'analyse du moteur JS (impliquant : l'étape d'analyse JS, l'étape de prétraitement, la phase d'exécution génère le contexte d'exécution, le VO (objet global), la chaîne de portée, le mécanisme de recyclage, etc.)
Vous constaterez qu'il y en a tellement processus se produisant entre une simple URL d'entrée et le rendu de la page, avez-vous l'impression que cela plante instantanément ? (Ne vous inquiétez pas, nous n'entrerons pas dans cette profondeur dans ce chapitre. Nous allons d'abord vous apprendre à répondre à cette question ? . Cette section sera abordée dans un article séparé plus tard)
- Le navigateur obtient l'adresse IP du nom de domaine via le serveur DNS et envoie une requête à cette adresse IP. Demande d'obtention du texte HTML
- Le processus de rendu du navigateur. analyse le texte HTML et construit l'arborescence DOM
- Lors de l'analyse du HTML, s'il rencontre un style ou un fichier de style en ligne, il téléchargera et construira les règles de style. S'il rencontre un script JavaScript, il l'exécutera.
- Une fois l'arborescence DOM et CSSOM construits, le processus de rendu fusionne les deux dans un arbre de rendu
- Le processus de rendu commence à disposer l'arbre de rendu et à générer un arbre de mise en page
- Arbre de rendu versus arbre de mise en page Réaliser le dessin et générer enregistrements de dessin
4. Comment le navigateur analyse-t-il le code ?
Parse HTML
Le HTML est analysé ligne par ligne et le moteur de rendu du navigateur analysera et convertira le document HTML en nœuds DOM.
- Parse Html dans de nombreux jetons
- Parse jetons dans des objets
- combines objets dans un arbre Dom
Parse CSS
Le navigateur analysera les sélecteurs CSS de droite à gauche
Nous savons que l'arborescence DOM et l'arborescence CSSOM sont fusionnées dans l'arborescence de rendu, qui attache en fait le CSSOM à l'arborescence DOM, de sorte que l'arborescence DOM doit être parcourue en fonction des informations fournies par le sélecteur.
Regardons un exemple :
<style>
.nav .title span {color:blue}
</style>
<div class='nav'>
<div class='title'>
<span>南玖</span>
</div>
<div class="sub_title">前端</header>
</div>
Correspondance de droite à gauche :
Trouvez d'abord tous les spans de nœuds les plus à droite, et pour chaque span, recherchez vers le haut le nœud div.title
de h3 et puis vers le haut Lorsque le nœud
de div.nav trouve enfin l'élément racine html, le parcours de cette branche se termine.
Parse JS
Il existe un outil d'analyse js dans le navigateur, qui est spécialement utilisé pour analyser notre code js.
Lorsque le navigateur rencontre du code js, il appelle immédiatement "l'analyseur js" au travail.
L'analyseur trouvera toutes les variables, fonctions, paramètres, etc. dans js et attribuera la valeur de la variable à undefined.
Sortez la fonction dans un bloc fonctionnel et stockez-la dans l'entrepôt. Une fois cela fait, le code commence à être analysé ligne par ligne (de haut en bas, de gauche à droite), puis mis en correspondance avec l'entrepôt.
5.Quelle est la différence entre DOMContentLoaded et Load ?
- DOMContentLoaded : déclenché uniquement une fois l'analyse DOM terminée, à l'exclusion des feuilles de style, des images et d'autres ressources.
- Chargement : déclenché lorsque tous les DOM, feuilles de style, scripts, images et autres ressources de la page ont été chargés.
6. Quelle est la différence entre la refonte du navigateur et la réorganisation du domaine ?
-
Réarrangement : Une partie de l'arbre de rendu ou l'ensemble de l'arbre de rendu doit être réanalysé et la taille des nœuds doit être recalculée, ce qui se traduit par une régénération de la mise en page et une réorganisation des éléments
-
Redessin : En raison de changements dans le propriétés géométriques ou styles des nœuds Les changements, tels que les éléments d'arrière-plan des éléments, se manifestent par la modification de l'apparence de certains éléments. déclencher le redessinage et la refusion ?
Toute modification des informations utilisées pour construire l'arbre de rendu entraînera une redistribution ou un redessinage :
Ajouter, supprimer, mettre à jour les nœuds DOM Masquer un nœud DOM via l'affichage : aucun - déclencher une redistribution et redessiner Masquer un nœud DOM via la visibilité : caché - déclenche uniquement un redessin, car il n'y a pas de changements géométriques
Déplacer ou animer des nœuds DOM dans la page
Ajouter une feuille de style et ajuster les propriétés du style - Comportement de l'utilisateur, tel que redimensionner la fenêtre, changer la taille de la police ou faire défiler.
-
-
- Comment éviter de redessiner ou de refusionner ?
-
-
Changement de styles concentré : par exemple, utilisez la classe pour changer collectivement de stylesUtilisez document.createDocumentFragment()
: nous pouvons créer un document libre de l'arborescence DOM via le nœud createDocumentFragment, puis des opérations par lots sont effectuées sur ce nœud, et finalement insérées dans l'arborescence DOM, de sorte qu'une seule redistribution est déclenchée
7.为什么JS是单线程的?
这主要与JS的用途有关,JS作为浏览器的脚本语言,最初主要是实现用户与浏览器的交互,以及操作DOM。这就决定了它只能是单线程,否则会带来许多复杂的同步问题。
举个例子: 如果JS是多线程的,其中一个线程要修改一个DOM元素,另外一个线程想要删除这个DOM元素,这时候浏览器就不知道该听谁的。所以为了避免复杂性,从一诞生,JavaScript就被设计成单线程。
为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质
8.CSS加载会阻塞DOM吗?
先上结论
-
CSS
不会阻塞DOM
的解析,但会阻塞DOM
的渲染
-
CSS
会阻塞JS
执行,但不会阻塞JS
文件的下载
CSSOM的作用
第一个是提供给JavaScript操作样式表的能力
第二个是为布局树的合成提供基础的样式信息
这个CSSOM体现在DOM中就是document.styleSheets
Les bits du calque de composition L'image sera synthétisée par le GPU
, qui est plus rapide que le traitement du CPU
Lorsque repeindre
est nécessaire, seul repaint
lui-même n'affectera pas les autres calques
Pour les effets transformation
et opacité
, mise en page code> et <code ne seront pas d>paint
La meilleure façon d'améliorer un calque de composition est d'utiliser la propriété CSS will-change
-
7. Pourquoi JS est-il monothread ?
Cela est principalement lié à l'objectif de JS. En tant que langage de script du navigateur, JS était initialement principalement utilisé pour réaliser l'interaction entre l'utilisateur et le navigateur et pour faire fonctionner le DOM. Cela détermine qu'il ne peut être qu'un seul thread, sinon cela entraînera de nombreux problèmes de synchronisation complexes.
Par exemple : Si JS est multi-thread, un thread veut modifier un élément DOM et un autre thread veut supprimer l'élément DOM, alors le navigateur ne sait pas qui écouter. Ainsi, afin d'éviter toute complexité, JavaScript a été conçu pour être monothread depuis sa naissance.
Afin de profiter de la puissance de calcul des CPU multicœurs, HTML5 propose le standard Web Worker, qui permet aux scripts JavaScript de créer plusieurs threads, mais les threads enfants sont entièrement contrôlés par le thread principal et ne doivent pas faire fonctionner le DOMAINE. Par conséquent, cette nouvelle norme ne change pas la nature monothread de JavaScript
8. Le chargement CSS bloquera-t-il le DOM ? Tout d'abord la conclusion🎜🎜🎜🎜CSS
ne bloquera pas l'analyse du DOM
, mais il bloquera le rendu du DOM 🎜🎜<code>CSS
bloquera l'exécution de JS
, mais ne bloquera pas le téléchargement des fichiers JS
🎜🎜
🎜 Le rôle du CSSOM est reflété dans le DOM sous la forme document .styleSheets
🎜🎜🎜🎜Nous pouvons le voir dans le processus de rendu du navigateur mentionné précédemment : 🎜🎜🎜🎜DOM et CSSOM sont généralement construits en parallèle, donc 🎜Le chargement CSS ne bloquera pas Analyse DOM🎜🎜🎜 🎜🎜L'arbre de rendu dépend de l'arbre DOM et de l'arbre CSSOM, il doit donc attendre que les deux soient chargés avant de pouvoir commencer à créer le rendu, donc 🎜Le chargement CSS bloquera le rendu du DOM🎜🎜🎜🎜🎜 Puisque JavaScript peut faire fonctionner DOM et CSS , si l'interface est rendue en modifiant les propriétés de ces éléments (c'est-à-dire que le thread JavaScript et le thread UI sont exécutés en même temps), les éléments obtenus avant et après le thread de rendu peuvent être incompatible. Ainsi, afin d'éviter des résultats de rendu inattendus, le navigateur définit le 🎜thread de rendu GUI et le thread JavaScript pour qu'ils s'excluent mutuellement🎜🎜🎜🎜🎜🎜🎜JS doit attendre le téléchargement du CSS. Pourquoi est-ce ? (CSS bloque l'exécution du DOM)🎜🎜🎜
Si le contenu du script JS
doit obtenir le style de l'élément, alors il doit s'appuyer sur du CSS
. Étant donné que le navigateur ne peut pas détecter ce qui se passe dans JS
, afin d'éviter l'acquisition de styles, il doit attendre que tous les styles précédents soient téléchargés avant d'exécuter JS
. Cependant, les fichiers JS et CSS sont téléchargés en parallèle. Le fichier CSS sera chargé et exécuté avant l'exécution du fichier JS suivant, donc JS
脚本的内容是获取元素的样式,那它就必然依赖CSS
。因为浏览器无法感知JS
内部到底想干什么,为避免样式获取,就只好等前面所有的样式下载完毕再执行JS
。但JS文件与CSS文件下载是并行的,CSS文件会在后面的JS文件执行前先加载执行完毕,所以CSS会阻塞后面JS的执行
避免白屏,提高CSS的加载速度
- 使用CDN(CDN会根据你的网络状况,挑选最近的一个具有缓存内容的节点为你提供资源,因此可以减少加载时间)
- 对CSS进行压缩
- 合理使用缓存
- 减少http请求数,合并CSS文件
9.JS会阻塞页面吗?
先上结论
JS会阻塞DOM的解析,因此也就会阻塞页面的加载
这也是为什么我们常说要把JS文件放在最下面的原因
由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。
因此为了防止渲染出现不可预期的结果,浏览器设置 **「GUI 渲染线程与 JavaScript 引擎为互斥」**的关系。
当 JavaScript 引擎执行时 GUI 线程会被挂起,GUI 更新会被保存在一个队列中等到引擎线程空闲时立即被执行。
当浏览器在执行 JavaScript 程序的时候,GUI 渲染线程会被保存在一个队列中,直到 JS 程序执行完成,才会接着执行。
因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
10.defer和async的区别?
- 两者都是异步去加载外部JS文件,不会阻塞DOM解析
- Async是在外部JS加载完成后,浏览器空闲时,Load事件触发前执行,标记为async的脚本并不保证按照指定他们的先后顺序执行,该属性对于内联脚本无作用 (即没有**「src」**属性的脚本)。
- defer是在JS加载完成后,整个文档解析完成后,触发
DOMContentLoaded
事件前执行,如果缺少 src
CSS bloquera l'exécution des JS suivants
Évitez l'écran blanc et améliorez l'apparence. vitesse de chargement de CSS
Utilisez CDN (CDN sélectionnera le nœud le plus proche avec le contenu mis en cache pour vous fournir des ressources en fonction des conditions de votre réseau, afin de réduire le temps de chargement) Compressez CSS Utilisez le cache de manière raisonnable Réduire le nombre de requêtes http, fusionner les fichiers CSS9. JS bloquera-t-il la page ?
Concluons d'abord
JS bloquera le parsing du DOM, et donc bloquera le chargement de la page
C'est pourquoi on dit souvent qu'il faut mettre le fichier JS en bas
Puisque JavaScript peut manipuler le DOM, si vous modifiez les propriétés de ces éléments lors du rendu de l'interface (c'est-à-dire que le thread JavaScript et le thread UI s'exécutent en même temps), les données des éléments obtenues avant et après le thread de rendu peut être incohérent.
Par conséquent, afin d'éviter des résultats de rendu inattendus, le navigateur définit la relation **"Le fil de rendu GUI et le moteur JavaScript s'excluent mutuellement"**. Lors de l'exécution du moteur JavaScript, le thread GUI sera suspendu et les mises à jour de l'interface graphique seront enregistrées dans une file d'attente et exécutées immédiatement lorsque le thread du moteur est inactif.
Lorsque le navigateur exécute un programme JavaScript, le fil de rendu de l'interface graphique sera enregistré dans une file d'attente et ne sera exécuté que lorsque le programme JS sera terminé. Donc si le temps d'exécution de JS est trop long, cela entraînera un rendu de la page incohérent, donnant l'impression que le rendu et le chargement de la page sont bloqués.
10. Quelle est la différence entre différer et asynchrone ?
Les deux chargent les fichiers JS externes de manière asynchrone et ne bloqueront pas l'analyse DOM.
- Async est exécuté une fois le chargement JS externe terminé, lorsque le navigateur est inactif et avant le déclenchement de l'événement Load. Les scripts marqués comme asynchrones ne sont pas garantis. pour suivre le Spécifiez l'ordre dans lequel ils sont exécutés. Cet attribut n'a aucun effet sur les scripts en ligne (c'est-à-dire les scripts sans l'attribut "src").
- defer est exécuté après le chargement du JS, après l'analyse de l'intégralité du document et avant le déclenchement de l'événement
DOMContentLoaded
si l'attribut src
(c'est-à-dire le script intégré). est manquant, cet attribut ne devra pas être utilisé car il ne fonctionne pas dans ce cas
- 11. Mécanisme de récupération de place du navigateur
Le nettoyage de la mémoire est un mécanisme de gestion automatique de la mémoire. La mémoire dynamique de votre ordinateur doit être libérée lorsqu'elle n'est plus nécessaire.
Il convient de noter que automatique signifie que le navigateur peut automatiquement nous aider à recycler les déchets de mémoire, mais cela ne signifie pas que nous n'avons pas besoin de nous soucier de la gestion de la mémoire. S'il ne fonctionne pas correctement, un débordement de mémoire se produira toujours en JavaScript. , provoquant le crash du système. 🎜🎜🎜Étant donné que les chaînes, tableaux, objets, etc. n'ont pas de tailles fixes, ils doivent être alloués dynamiquement lorsque leurs tailles sont connues. Chaque fois qu'un programme JavaScript crée une chaîne, un tableau ou un objet, l'interpréteur doit allouer de la mémoire pour stocker cette entité. 🎜🎜L'interpréteur JavaScript peut détecter quand le programme n'utilise plus un objet. Lorsqu'il détermine que l'objet est inutile, il sait que l'objet n'est plus nécessaire et peut libérer la mémoire qu'il occupe. 🎜🎜Il existe deux méthodes de collecte des déchets généralement utilisées par les navigateurs : 🎜mark scanning🎜, 🎜reference counting🎜. 🎜🎜🎜🎜Mark clearing🎜🎜🎜🎜🎜Il s'agit de la méthode de garbage collection la plus couramment utilisée en JavaScript🎜🎜🎜Depuis 2012, tous les navigateurs modernes ont utilisé la méthode de garbage collection de mark clearing, à l'exception des versions inférieures d'IE Reference counting. 🎜🎜🎜Alors, qu’est-ce que la suppression des marques ? 🎜🎜🎜🎜Il existe un objet global en JavaScript. Périodiquement, le garbage collector partira de cet objet global, trouvera tous les objets référencés à partir de cet objet global, puis trouvera les objets référencés par ces objets... Pour ces objets actifs marquage, c’est la phase de marquage. L'étape de nettoyage consiste à nettoyer les objets qui ne sont pas marqués. 🎜🎜🎜Un problème avec l'effacement des marques est qu'après l'effacement, l'espace mémoire est discontinu, c'est-à-dire qu'une fragmentation de la mémoire se produit. Si un espace mémoire continu relativement important est nécessaire ultérieurement, il ne répondra pas aux exigences. La méthode 🎜organisation des marques🎜 peut résoudre efficacement ce problème. 🎜🎜Dans le processus de marquage, le concept de marquage tricolore est introduit. Les trois couleurs sont : 🎜🎜🎜Blanc : les objets non marqués, c'est-à-dire les objets inaccessibles (objets non scannés), peuvent être recyclés 🎜🎜Gris. : Objets qui ont été marqués (objets accessibles), mais les objets n'ont pas encore été scannés et ne peuvent pas être recyclés 🎜🎜Noir : ont été scannés (objets accessibles) et ne peuvent pas être recyclés 🎜🎜🎜🎜 Tri des marquages : 🎜🎜La phase de marquage n'est pas différente de la méthode mark and clear, sauf qu'une fois le marquage terminé, la méthode mark and clear déplacera les objets survivants d'un côté de la mémoire et nettoiera enfin la mémoire limite.
Comptage de références
La signification du comptage de références est de suivre le nombre de fois où chaque valeur est référencée. Lorsqu'une variable A reçoit une valeur, le nombre de références à cette valeur est de 1. Lorsque la variable A est réaffectée, le nombre de références à la valeur précédente est réduit de 1. Lorsque le nombre de références devient 0, cela signifie qu'il n'y a plus moyen d'accéder à cette valeur, donc la mémoire occupée par cette valeur peut être effacée.
La plupart des navigateurs ont abandonné cette méthode de recyclage
Fuite mémoire
Pour éviter les fuites mémoire, une fois que les données ne sont plus utilisées, il est préférable de définir leur valeur sur null code>Pour libérer sa référence, cette méthode est appelée <code>null
来释放其引用,这个方法叫做接触引用
哪些情况会造成内存泄漏?如何避免?
以 Vue 为例,通常有这些情况:
- 监听在
window/body
等事件没有解绑
- 绑在
EventBus
的事件没有解绑
-
Vuex
的 $store
,watch
了之后没有 unwatch
- 使用第三方库创建,没有调用正确的销毁函数
解决办法:beforeDestroy
中及时销毁
- 绑定了
DOM/BOM
对象中的事件 addEventListener
,removeEventListener
。
- 观察者模式
$on
,$off
处理。
- 如果组件中使用了定时器,应销毁处理。
- 如果在
mounted/created
钩子中使用了第三方库初始化,对应的销毁。
- 使用弱引用
weakMap
、weakSet
。
浏览器中不同类型变量的内存都是何时释放的?
-
引用类型
-
基本类型
- 如果处于闭包的情况下,要等闭包没有引用才会被 V8 回收。
- 非闭包的情况下,等待 V8 的新生代切换的时候回收。
12.说一说浏览器的缓存机制?
认识浏览器缓存
当浏览器请求一个网站时,会加载各种资源,对于一些不经常变动的资源,浏览器会将他们保存在本地内存中,下次访问时直接加载这些资源,提高访问速度。
如何知道资源是请求的服务器还是读取的缓存呢?
看上面这张图,有些资源的size值是大小,有些是from disk cache
,有些是from memory cache
,显示大小的是请求的服务器资源,而显示后面两种的则是读取的缓存。
-
disk cache: 就是将资源存储在磁盘中,等待下次访问时不需重新下载,直接从磁盘中读取,它的直接操作对象为
CurlCacheManager
Référence de contact
Quelles situations provoqueront des fuites de mémoire ? Comment l'éviter ?
En prenant Vue comme exemple, il existe généralement ces situations :
Les événements surveillés dans window/body ne sont pas indépendants |
Les événements liés à EventBus sont non dissocié Après avoir dissocié le $store de |
Vuex , watch n'a pas unwatch
|
créé à l'aide d'un bibliothèque tierce. La fonction de destruction correcte n'est pas appelée
Solution : Détruire à temps dans beforeDestroy
| Lier l'événement addEventListenerDOM/BOM.
objet /code>, removeEventListener
. | Mode observateur $on
, traitement $off
. | Si une minuterie est utilisée dans un composant, elle doit être détruite.
Si une initialisation de bibliothèque tierce est utilisée dans le hook monté/créé
, elle sera détruite en conséquence. | Utilisez les références faibles weakMap
, weakSet
. |
| Quand les mémoires des différents types de variables dans le navigateur sont-elles publiées ?
| Les types de référence | sont automatiquement recyclés par V8 lorsqu'il n'y a plus de référence. |
Type basique🎜🎜S'il est dans une fermeture, il ne sera pas recyclé par V8 tant que la fermeture n'aura plus de référence. 🎜🎜En cas de non fermeture, il sera recyclé en attendant le switch nouvelle génération du V8. 🎜🎜🎜🎜12. Parlez-nous du mécanisme de mise en cache du navigateur ?
🎜🎜🎜Comprendre le cache du navigateur🎜🎜🎜🎜Lorsque le navigateur demande un site Web, il chargera diverses ressources pour certaines ressources qui ne changent pas fréquemment, le navigateur les enregistrera dans la mémoire locale pour la prochaine fois. Chargez ces ressources. directement pendant l’accès pour améliorer la vitesse d’accès. 🎜🎜🎜🎜Comment savoir si la ressource est demandée par le serveur ou lue depuis le cache ? 🎜🎜🎜🎜🎜 🎜Regardez l'image ci-dessus. La valeur de taille de certaines ressources est la taille, certaines proviennent du du cache disque
et d'autres du du cache mémoire
. ressource serveur demandée. Les deux dernières sont affichées comme cache de lecture. 🎜🎜🎜cache disque : 🎜 consiste à stocker les ressources sur le disque et à attendre le prochain accès sans retélécharger. Il peut être lu directement à partir du disque. Son objet d'opération directe est CurlCacheManager
. . (L'efficacité est plus lente que le cache mémoire, mais la capacité de stockage est grande et la durée de stockage est longue) 🎜🎜🎜cache mémoire : 🎜 Il s'agit de mettre en cache les ressources dans la mémoire, et d'attendre le prochain accès sans retélécharger, lire directement à partir de la mémoire. (C'est le plus rapide du point de vue de l'efficacité, et le plus court du point de vue du temps de survie.) 🎜🎜🎜🎜🎜🎜-🎜🎜cache mémoire🎜🎜cache disque🎜🎜🎜🎜🎜🎜Mêmes points🎜🎜 peuvent Stockez uniquement certains fichiers de ressources dérivées🎜🎜Seuls certains fichiers de ressources dérivées peuvent être stockés🎜🎜🎜🎜La différence🎜🎜Les données seront effacées à la sortie du processus🎜🎜Les données ne seront pas effacées à la sortie du processus🎜🎜🎜🎜Stockage ressources🎜🎜Général Les scripts, les polices et les images seront stockés en mémoire. Généralement, les non-scripts seront stockés en mémoire, comme les CSS, etc.🎜🎜🎜🎜.Classification du cache du navigateur
- Cache fort
- Cache de négociation
Lorsque le navigateur demande des ressources au serveur, il détermine d'abord s'il atteint le cache fort, et s'il échoue, il détermine s'il atteint le cache de négociation
Cache fort
Lorsque le navigateur charge les ressources, il déterminera d'abord si le cache fort est touché en fonction du en-tête
de la ressource du cache local s'il atteint. , la ressource dans le cache sera utilisée directement et ne sera plus renvoyée au cache. Le serveur envoie la requête. header
中判断是否命中强缓存,如果命中则直接使用缓存中的资源,不会再向服务器发送请求。 (这里的header中的信息指的是 expires
和 cache-control
)
该字段是 http1.0 时的规范,它的值为一个绝对时间的 GMT 格式的时间字符串,比如 Expires:Mon,18 Oct 2066 23:59:59 GMT。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。所以这种方式很快在后来的HTTP1.1版本中被抛弃了。
Cache-Control 是 http1.1 时出现的 header 信息,主要是利用该字段的 max-age 值来进行判断,它是一个相对时间,例如 Cache-Control:max-age=3600
,代表着资源的有效期是 3600 秒。cache-control 除了该字段外,还有下面几个比较常用的设置值:
no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。
no-store:禁止使用缓存,每一次都要重新请求数据。
public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。
private:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。
Cache-Control 与 Expires 可以在服务端配置同时启用,同时启用的时候 Cache-Control 优先级高。
协商缓存
当强缓存没命中时,浏览器会发送一个请求到服务器,服务器根据 header
中的信息来判断是否命中协商缓存。如果命中,则返回304 ,告诉浏览器资源未更新,可以使用本地缓存。 (这里的header信息指的是Last-Modify/If-Modify-Since
和 ETag/If-None-Match
(Les informations dans l'en-tête ici font référence à expires
et cache-control
)
Ce champ est
http1.0 spécification d'heure, sa valeur est une chaîne d'heure
heure absolue au format GMT, telle que Expires:Mon,18 Oct 2066 23:59:59 GMT. Cette heure représente l'heure d'expiration de cette ressource. Avant cette heure, le cache est atteint. Cette méthode présente un inconvénient évident. Étant donné que le délai d'expiration est un délai absolu, lorsque l'écart de temps entre le serveur et le client est important, cela entraînera une confusion dans le cache. Cette méthode a donc été rapidement abandonnée dans la version ultérieure de HTTP 1.1.
Cache-Control
Par exemple, Cache-Control:max-age=3600
signifie que la période de validité de la ressource est de 3600 secondes. En plus de ce champ, cache-control a également les valeurs de paramètre suivantes, plus couramment utilisées :
no-cache
: Vous devez négocier le cache et envoyer une demande au serveur pour confirmer si vous souhaitez utiliser le cache. no-store
: désactivez l'utilisation du cache et demandez à nouveau des données à chaque fois. public : peut être mis en cache par tous les utilisateurs, y compris les utilisateurs finaux et les serveurs proxy intermédiaires tels que CDN.
privé : il ne peut être mis en cache que par le navigateur de l'utilisateur final et n'est pas autorisé à être mis en cache par des serveurs de cache relais tels que CDN.
Cache-Control et Expires peuvent être activés en même temps dans la configuration du serveur Lorsqu'il est activé en même temps, Cache-Control a une priorité plus élevée.
Cache de négociation🎜🎜Lorsque le cache fort manque, le navigateur envoie une requête au serveur, et le serveur détermine si le cache de négociation est atteint en fonction des informations contenues dans en-tête
. S'il atteint, 🎜304🎜 est renvoyé, indiquant au navigateur que la ressource n'a pas été mise à jour et que le cache local peut être utilisé. 🎜(Les informations d'en-tête ici font référence à Last-Modify/If-Modify-Since
et ETag/If-None-Match
)🎜🎜🎜🎜🎜🎜Last-Modify / If-Modify-Since🎜🎜🎜🎜🎜Lorsque le navigateur demande une ressource pour la première fois, Last-Modify sera ajouté à l'en-tête renvoyé par le serveur. Last-modify est une heure qui identifie l'heure de la dernière modification de la ressource. . 🎜🎜Lorsque le navigateur demandera à nouveau la ressource, l'en-tête de la requête contiendra If-Modify-Since, qui est le Last-Modify renvoyé avant la mise en cache. Une fois que le serveur a reçu If-Modify-Since, il détermine si le cache est atteint en fonction de l'heure de la dernière modification de la ressource. 🎜🎜Si le cache est atteint, 304 est renvoyé et le contenu de la ressource n'est pas renvoyé et Last-Modify n'est pas renvoyé. 🎜🎜Inconvénients :🎜🎜Si les ressources changent dans un court laps de temps, Last-Modified ne changera pas. 🎜🎜Changements cycliques. Si cette ressource est modifiée pour retrouver son apparence d'origine au cours d'un cycle, nous pensons qu'elle peut être mise en cache, mais Last-Modified ne le pense pas, il existe donc un ETag. 🎜🎜🎜🎜🎜ETag/If-None-Match🎜🎜🎜🎜🎜La différence avec Last-Modify/If-Modify-Since est que Etag/If-None-Match renvoie un code de vérification. ETag peut garantir que chaque ressource est unique et les modifications de ressources entraîneront des modifications d'ETag. Le serveur détermine si le cache est atteint en fonction de la valeur If-None-Match envoyée par le navigateur. 🎜🎜La différence avec Last-Modified est que lorsque le serveur renvoie une réponse 304 Not Modified, puisque l'ETag a été régénéré, l'ETag sera renvoyé dans l'en-tête de réponse, même si l'ETag n'a pas changé par rapport au précédent. 🎜🎜🎜Last-Modified et ETag peuvent être utilisés ensemble. Le serveur vérifiera d'abord l'ETag s'il est cohérent, il continuera à comparer Last-Modified et décidera enfin s'il doit renvoyer 304. 🎜🎜🎜🎜🎜Résumé🎜🎜🎜🎜🎜Lorsque le navigateur accède à une ressource déjà visitée, ses étapes sont les suivantes : 🎜🎜🎜1 Vérifiez d'abord si le cache fort est touché. S'il atteint ?, utilisez le cache directement🎜🎜2. . Si le cache fort n'est pas atteint, la requête sera envoyée au serveur pour voir si elle atteint le cache de négociation 🎜🎜3 Si le cache de négociation est atteint, le serveur renverra 304 pour indiquer au navigateur qu'il s'agit du cache local. peut être utilisé. 4. Si le cache de négociation n'est pas atteint, le serveur renverra de nouvelles ressources au navigateur🎜13.什么是浏览器的同源策略,以及跨域?
同源策略
同源策略是浏览器的一种自我保护行为。所谓的同源指的是:协议,域名,端口均要相同
浏览器中大部分内容都是受同源策略限制的,但是以下三个标签不受限制:
<img src="..." / alt="Jetez un œil à ces questions d'entretien de navigateur. À combien pouvez-vous répondre correctement ?" >
<link href="..." />
<script src="..."></script>
跨域
跨域指的是浏览器不能执行其它域名下的脚本。它是由浏览器的同源策略限制的。
你可能会想跨域请求到底有没有发送到服务器?
事实上,跨域请求时能够发送到服务器的,并且服务器也能过接受的请求并正常返回结果,只是结果被浏览器拦截了。
跨域解决方案(列出几个常用的)
它主要是利用script标签不受浏览器同源策略的限制,可以拿到从其他源传输过来的数据,需要服务端支持。
优缺点:
兼容性比较好,可用于解决主流浏览器的跨域数据访问的问题。缺点就是仅支持get请求,具有局限性,不安全,可能会受到XSS攻击。
思路:
- 声明一个回调函数,其函数名(如show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。
- 创建一个
<script></script>
标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=show)。
- 服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是show,它准备好的数据是
show('南玖')
。
- 最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(show),对返回的数据进行操作。
// front
function jsonp({ url, params, callback }) {
return new Promise((resolve, reject) => {
let script = document.createElement('script')
window[callback] = function(data) {
resolve(data)
document.body.removeChild(script)
}
params = { ...params, callback } // wd=b&callback=show
let arrs = []
for (let key in params) {
arrs.push(`${key}=${params[key]}`)
}
script.src = `${url}?${arrs.join('&')}`
document.body.appendChild(script)
})
}
jsonp({
url: 'http://localhost:3000/say',
params: { wd: 'wxgongzhonghao' },
callback: 'show'
}).then(data => {
console.log(data)
})
// server 借助express框架
let express = require('express')
let app = express()
app.get('/say', function(req, res) {
let { wd, callback } = req.query
console.log(wd) // Iloveyou
console.log(callback) // show
res.end(`${callback}('关注前端南玖')`)
})
app.listen(3000)
上面这段代码相当于向http://localhost:3000/say?wd=wxgongzhonghao&callback=show
这个地址请求数据,然后后台返回show('关注前端南玖')
,最后会运行show()这个函数,打印出'关注前端南玖'
CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。
CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。
浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。
服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。
虽然设置 CORS 和前端没什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求和复杂请求。
简单请求: (满足以下两个条件,就是简单请求)
1.请求方法为以下三个之一:
2.Content-Type的为以下三个之一:
- text-plain
- multiparty/form-data
- application/x-www-form-urlencoded
复杂请求:
不是简单请求那它肯定就是复杂请求了。复杂请求的CORS请求,会在正式发起请求前,增加一次HTTP查询请求,称为预检 请求,该请求是option方法的,通过该请求来知道服务端是否允许该跨域请求。
Nginx反向代理
Nginx 反向代理的原理很简单,即所有客户端的请求都必须经过nginx处理,nginx作为代理服务器再将请求转发给后端,这样就规避了浏览器的同源策略。
14.说说什么是XSS攻击
什么是XSS?
XSS 全称是 Cross Site Scripting
,为了与css
区分开来,所以简称XSS
,中文叫作跨站脚本
XSS是指黑客往页面中注入恶意脚本,从而在用户浏览页面时利用恶意脚本对用户实施攻击的一种手段。
XSS能够做什么?
- 窃取Cookie
- 监听用户行为,比如输入账号密码后之间发给黑客服务器
- 在网页中生成浮窗广告
- 修改DOM伪造登入表单
XSS实现方式
- 存储型XSS攻击
- 反射型XSS攻击
- 基于DOM的XSS攻击
如何阻止XSS攻击?
对输入脚本进行过滤或转码
对用户输入的信息过滤或者转码,保证用户输入的内容不能在HTML解析的时候执行。
利用CSP
该安全策略的实现基于一个称作 Content-Security-Policy
的HTTP首部。(浏览器内容安全策略)它的核心思想就是服务器决定浏览器加载那些资源。
- 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
- 禁止向第三方域提交数据,这样用户数据也不会外泄;
- 提供上报机制,能帮助我们及时发现 XSS 攻击。
- 禁止执行内联脚本和未授权的脚本;
利用 HttpOnly
由于很多 XSS 攻击都是来盗用 Cookie 的,因此还可以通过使用 HttpOnly 属性来保护我们 Cookie 的安全。这样子的话,JavaScript 便无法读取 Cookie 的值。这样也能很好的防范 XSS 攻击。
通常服务器可以将某些 Cookie 设置为 HttpOnly 标志,HttpOnly 是服务器通过 HTTP 响应头来设置的,下面是打开 Google 时,HTTP 响应头中的一段:
set-cookie: NID=189=M8l6-z41asXtm2uEwcOC5oh9djkffOMhWqQrlnCtOI; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly
对于不受信任的输入,可以限制输入长度
15.说说什么是CSRF攻击?
什么是CSRF攻击?
CSRF 全称 Cross-site request forgery
,中文为跨站请求伪造 ,攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。 CSRF攻击就是黑客利用用户的登录状态,并通过第三方站点来干一些嘿嘿嘿的坏事。
几种常见的攻击类型
1.GET类型的CSRF
GET类型的CSRF非常简单,通常只需要一个HTTP请求:
<img src="http://bank.example/withdraw?amount=10000&for=hacker" alt="Jetez un œil à ces questions d'entretien de navigateur. À combien pouvez-vous répondre correctement ?" >
在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker
发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。
2.POST类型的CSRF
这种类型的CSRF利用起来通常使用的是一个自动提交的表单,如:
<form action="http://bank.example/withdraw" method=POST>
<input type="hidden" name="account" value="xiaoming" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。
3.链接类型的CSRF
链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
重磅消息!!
<a/>
由于之前用户登录了信任的网站A,并且保存登录状态,只要用户主动访问上面的这个PHP页面,则表示攻击成功。
CSRF的特点
- 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生。
- 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据。
- 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”。
- 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪。
CSRF通常是跨域的,因为外域通常更容易被攻击者掌控。但是如果本域下有容易被利用的功能,比如可以发图和链接的论坛和评论区,攻击可以直接在本域下进行,而且这种攻击更加危险。
防护策略
Un pirate informatique ne peut utiliser que le cookie
de la victime pour frauder la confiance du serveur, mais le pirate informatique ne peut pas obtenir le **"cookie"** et ne peut pas voir le contenu du **"cookie"cookie
骗取服务器的信任,但是黑客并不能凭借拿到**「cookie」**,也看不到 **「cookie」的内容。另外,对于服务器返回的结果,由于浏览器「同源策略」**的限制,黑客也无法进行解析。
这就告诉我们,我们要保护的对象是那些可以直接产生数据改变的服务,而对于读取数据的服务,则不需要进行CSRF
. De plus, les pirates ne peuvent pas analyser les résultats renvoyés par le serveur en raison des limitations de la « Same Origin Policy »** du navigateur. Cela nous indique que les objets que nous voulons protéger sont des services qui peuvent directement produire des modifications de données, et pour les services qui lisent des données, il n'y a pas besoin de protection CSRF
. La clé de la protection est
"Mettez des informations dans la demande que les pirates ne peuvent pas falsifier"
Détection originale
Étant donné que la plupart des CSRF proviennent de sites Web tiers, nous interdisons directement les domaines externes (ou non Domaine de confiance noms) nous font des demandes.
La question est alors de savoir comment déterminer si la demande provient d'un domaine externe ?
Dans le protocole HTTP, chaque requête asynchrone porte deux Headers pour marquer le nom de domaine source : -
- Origin Header
Referer Header
Lorsque le navigateur initie une requête, ces deux Headers seront dans la plupart des cas apportés automatiquement et le contenu ne peut pas être personnalisé par le front-end. Le serveur peut déterminer le domaine source de la requête en analysant les noms de domaine dans ces deux en-têtes.
Utilisez l'en-tête Origin pour déterminer le nom de domaine source
Dans certaines requêtes liées au CSRF, le champ Origin sera porté dans l'en-tête demandé. Le champ contient le nom de domaine demandé (hors chemin et requête).
Si Origin existe, vous pouvez directement utiliser les champs dans Origin pour confirmer le nom de domaine source.
Mais Origin n'existe pas dans les deux cas suivants : -
Politique de même origine IE11 : IE 11 n'ajoutera pas l'en-tête Origin sur les requêtes CORS intersites, l'en-tête Referer sera toujours l'identifiant unique. La raison la plus fondamentale est que la définition de la même origine dans IE 11 est différente de celle des autres navigateurs. Il existe deux différences principales. Vous pouvez vous référer à la redirection
MDN Same-origin_policy#IE_Exceptions :
Origine après la redirection 302. Non inclus dans. les demandes redirigées car Origin peuvent être considérées comme des informations sensibles provenant d’autres sources. Dans le cas des redirections 302, l'URL est dirigée vers le nouveau serveur, le navigateur ne souhaite donc pas divulguer l'Origin vers le nouveau serveur.
Utilisez Referer Header pour déterminer le nom de domaine source
Selon le protocole HTTP, il existe un champ appelé Referer dans l'en-tête HTTP, qui enregistre l'adresse source de la requête HTTP. Pour les requêtes Ajax, les requêtes de ressources telles que les images et les scripts, Referer est l'adresse de la page qui initie la requête. Pour les sauts de page, Referer est l’adresse de la page précédente qui a ouvert l’historique des pages. Nous pouvons donc utiliser la partie Origin du lien dans le Referer pour connaître le nom de domaine source de la requête.
Cette méthode n'est pas infaillible. La valeur de Referer est fournie par le navigateur. Bien qu'il existe des exigences claires dans le protocole HTTP, chaque navigateur peut avoir des implémentations différentes de Referer, et il n'y a aucune garantie que le navigateur lui-même ne présente aucune faille de sécurité. . La méthode de vérification de la valeur du Referer repose sur un tiers (c'est-à-dire le navigateur) pour garantir la sécurité. En théorie, cela n'est pas très sûr. Dans certains cas, les attaquants peuvent masquer ou même modifier le Referer qu'ils demandent.
En 2014, le groupe de travail sur la sécurité des applications Web du W3C a publié le projet de politique de référencement, qui contient des dispositions détaillées sur la manière dont les navigateurs doivent envoyer le référent. À l'heure actuelle, la plupart des nouveaux navigateurs prennent en charge cette version, et nous pouvons enfin contrôler de manière flexible la stratégie de référencement de notre site Web. La nouvelle version de la politique de référencement stipule cinq politiques de référencement : aucun référent, aucun référent en cas de rétrogradation, origine uniquement, origine en cas d'origine croisée et URL non sécurisée. Les trois stratégies existantes : jamais, par défaut et toujours ont été renommées dans la nouvelle norme. Leur correspondance est la suivante :
|
Nom de la stratégie |
Valeur de l'attribut (nouvelle) |
Valeur de l'attribut (ancienne)
|
No Referrer |
no-Referrer |
jamais
| Aucun référent quand Télécharger | - |
URL non sécurisée | url-unsafe | toujours |
根据上面的表格因此需要把Referrer Policy的策略设置成same-origin,对于同源的链接和引用,会发送Referer,referer值为Host不带Path;跨域访问则不携带Referer。例如:aaa.com
引用bbb.com
的资源,不会发送Referer。
设置Referrer Policy的方法有三种:
在CSP设置
页面头部增加meta标签
a标签增加referrerpolicy属性
上面说的这些比较多,但我们可以知道一个问题:攻击者可以在自己的请求中隐藏Referer。如果攻击者将自己的请求这样填写:
<img src="http://bank.example/withdraw?amount=10000&for=hacker" referrerpolicy="no-referrer" alt="Jetez un œil à ces questions d'entretien de navigateur. À combien pouvez-vous répondre correctement ?" >
那么这个请求发起的攻击将不携带Referer。
另外在以下情况下Referer没有或者不可信:
1.IE6、7下使用window.location.href=url进行界面的跳转,会丢失Referer。
2.IE6、7下使用window.open,也会缺失Referer。
3.HTTPS页面跳转到HTTP页面,所有浏览器Referer都丢失。
4.点击Flash上到达另外一个网站的时候,Referer的情况就比较杂乱,不太可信。
无法确认来源域名情况
当Origin和Referer头文件不存在时该怎么办?如果Origin和Referer都不存在,建议直接进行阻止,特别是如果您没有使用随机CSRF Token(参考下方)作为第二次检查。
如何阻止外域请求
通过Header的验证,我们可以知道发起请求的来源域名,这些来源域名可能是网站本域,或者子域名,或者有授权的第三方域名,又或者来自不可信的未知域名。
我们已经知道了请求域名是否是来自不可信的域名,我们直接阻止掉这些的请求,就能防御CSRF攻击了吗?
且慢!当一个请求是页面请求(比如网站的主页),而来源是搜索引擎的链接(例如百度的搜索结果),也会被当成疑似CSRF攻击。所以在判断的时候需要过滤掉页面请求情况,通常Header符合以下情况:
Accept: text/html
Method: GET
但相应的,页面请求就暴露在了CSRF的攻击范围之中。如果你的网站中,在页面的GET请求中对当前用户做了什么操作的话,防范就失效了。
例如,下面的页面请求:
GET https://example.com/addComment?comment=XXX&dest=orderId
注:这种严格来说并不一定存在CSRF攻击的风险,但仍然有很多网站经常把主文档GET请求挂上参数来实现产品功能,但是这样做对于自身来说是存在安全风险的。
另外,前面说过,CSRF大多数情况下来自第三方域名,但并不能排除本域发起。如果攻击者有权限在本域发布评论(含链接、图片等,统称UGC),那么它可以直接在本域发起攻击,这种情况下同源策略无法达到防护的作用。
综上所述:同源验证是一个相对简单的防范方法,能够防范绝大多数的CSRF攻击。但这并不是万无一失的,对于安全性要求较高,或者有较多用户输入内容的网站,我们就要对关键的接口做额外的防护措施。
CSRF Token
前面讲到CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。
而CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开,也可以防范CSRF的攻击。
利用Cookie的SameSite属性
可以看看MDN对此的解释:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie/SameSite
SameSite
可以设置为三个值,Strict
、Lax
和None
。
在Strict
模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com
网站只能在sanyuan.com
域名当中请求才能携带 Cookie,在其他网站请求都不能。
在Lax
模式,就宽松一点了,但是只能在 get 方法提交表单
况或者a 标签发送 get 请求
的情况下可以携带 Cookie,其他情况均不能。
在None模式下,Cookie将在所有上下文中发送,即允许跨域发送。
更多编程相关知识,请访问:编程入门!!