


Ausführliche Erläuterung der Verwendung von ETag und bedingten Headern für das Caching
Laravel API-Leistungsoptimierung: Caching mit ETags und bedingten Headern
Wenn Sie eine Anwendung mit separatem Front-End und Back-End schreiben, müssen Sie darüber nachdenken, welche Art von Anfragen der Front-End-Client an die API senden wird, um erneut Daten vom Back-End abzurufen, auch wenn Sie dies nur tun Ich möchte überprüfen, ob der Front-End-Cache die hinzugefügten Daten verarbeiten kann. In Echtzeit aktualisiert. Basierend auf den oben genannten Anforderungen können Sie den ETag
-Header und bedingte Anforderungen verwenden. ETag
头 和 conditional requests。
在这篇博文中,我会简单的概括一下 ETag
, If-None-Match
和 If-Match
头是做什么的,然后再看看我是如何将这些应用到我们的package中的,这个软件包可以快速的将它实施到您的应用程序中。
是什么
让我们从这一切的核心内容开始,那就是 ETag
头。该头文件是表示其所在的确切状态下的响应主体的值。在很多情况下 ETag
的值将是内容的 hash
值,因为这是最容易生成和保证响应数据唯一性标识符的方法。
为了保证 ETag
头可用,我们必须使用条件请求。我们需要设置的第一个条件是 If-None-Match
头,这是一个用于 GET
的请求头。在后端接收到这个头之后,需要将它和当前的内容进行比较。如果值匹配的话,将只返回 304
状态码,和获取实体资源比较起来,响应结果的数据本身是很小的。这一切实施起来是非常简单的:如果你的第一个获取资源的 GET
请求返回了一个 ETag
数据,你的浏览器会自动的为接下来的资源的请求配置 If-None-Match
头。
这意味着,如果您的后端简单实现了 etag
和 if-none-match
,则可以减少从您的API传输到前端的数据量。
第二个请求条件使用的是 if-match
头。这被用来阻止 mid-air collisions 。 通俗的说,如果我们想要在后端更新数据,但是我们的前端数据已经过时,后端的更新应该被终止,而且前端也应该有提醒。 这和 if-none-match
的工作方式很类似。在获取到包含 ETag
值的资源之后,你可以提交一个 PATCH
请求并且设置一个和你之前接收到的 ETag
值相等的 If-Match
值。然后,后端将检查服务端当前可用的资源的 etag
值是否与您发送的资源相匹配。如果匹配,将允许您的更新。如果没有匹配,将返回412
状态码,让前端知道条件不匹配。
如何使用
如果你想要在 laravel
项目中使用这个条件请求插件包的话,你可以使用以下命令来安装:
$ composer require werk365/etagconditionals
然后在你的路由中添加 etag
中间件之后就可以使用了。如果你想研究中间件的工作原理,或者想要不通过我们的插件包来实现这个功能的话,请接着往下读!
SetEtag 中间件
正如您可能已经猜到的那样,我们可以通过中间件来很简单的实现这一功能。 Laravel
实际上已经为我们提供了一个 SetCacheHeaders
中间件来设置 ETag
头, 但是它不支持 HEAD
请求。 SetEtag
中间件的内容看起来是这样的:
public function handle(Request $request, Closure $next) { // Handle request $method = $request->getMethod(); // Support using HEAD method for checking If-None-Match if ($request->isMethod('HEAD')) { $request->setMethod('GET'); } //Handle response $response = $next($request); // Setting etag $etag = md5($response->getContent()); $response->setEtag($etag); $request->setMethod($method); return $response; }
我们首先要做的事情是获取请求的方法,以防我们想要修改它。然后,当我们在处理 HEAD
请求的时候,我们把它修改为 GET
请求,以确保请求的内容已经被加载而且可以被加密。在此之后,我们跳转到已经使用 md5()
方法加密后的响应主体内容。在返回响应之前,我们会将加密后的 hash
值作为 ETag
ETag
, If-None-Match
und If-Match
bewirken, und dann Schauen Sie sich an, wie ich diese auf unser Paket angewendet habe, damit Sie es schnell in Ihre Anwendung implementieren können. Was ist
Beginnen wir mit dem Kern des Ganzen, dem ETag
-Header. Dieser Header ist ein Wert, der den Antworttext in genau dem Zustand darstellt, in dem er sich befindet. In vielen Fällen ist der Wert des ETag
der Hash
-Wert des Inhalts, da dies der einfachste Weg ist, eine eindeutige Kennung für die Antwortdaten zu generieren und zu garantieren. Um sicherzustellen, dass der ETag
-Header verfügbar ist, müssen wir bedingte Anfragen verwenden. Die erste Bedingung, die wir festlegen müssen, ist der Header If-None-Match
, bei dem es sich um einen Anforderungsheader handelt, der für GET
verwendet wird. Nachdem das Backend diesen Header erhalten hat, muss es ihn mit dem aktuellen Inhalt vergleichen. Wenn die Werte übereinstimmen, wird nur der Statuscode 304
zurückgegeben. Im Vergleich zum Abrufen der Entitätsressource sind die Antwortergebnisdaten selbst sehr klein. All dies ist sehr einfach zu implementieren: Wenn Ihre erste GET
-Anfrage für eine Ressource ETag
-Daten zurückgibt, wird Ihr Browser automatisch die Anforderungskonfiguration der Ressource If-None- Match
-Header. 🎜🎜Das bedeutet, dass Sie die von Ihrer API an das Frontend übertragene Datenmenge reduzieren können, wenn Ihr Backend einfach etag
und if-none-match
implementiert. 🎜🎜Die zweite Anforderungsbedingung verwendet den Header if-match
. Dies dient dazu, 🎜Zusammenstöße in der Luft🎜 zu verhindern. Laienhaft ausgedrückt: Wenn wir Daten im Backend aktualisieren möchten, unsere Frontend-Daten jedoch veraltet sind, sollte die Aktualisierung des Backends beendet werden und es sollte eine Erinnerung im Frontend geben. Dies ähnelt der Funktionsweise von if-none-match
. Nachdem Sie die Ressource mit dem ETag
-Wert abgerufen haben, können Sie eine PATCH
-Anfrage senden und einen ETag
-Wert festlegen, der dem zuvor erhaltenen entspricht If-Match-Wert. Das Backend prüft dann, ob der etag
-Wert der aktuell auf dem Server verfügbaren Ressource mit der von Ihnen gesendeten Ressource übereinstimmt. Wenn es eine Übereinstimmung gibt, wird Ihr Update zugelassen. Wenn keine Übereinstimmung vorliegt, wird der Statuscode 412
zurückgegeben, um das Frontend darüber zu informieren, dass die Bedingungen nicht übereinstimmen. 🎜Verwendung
🎜Wenn Sie dieses Plug-in-Paket für bedingte Anforderungen imlaravel
-Projekt verwenden möchten, können Sie es mit dem folgenden Befehl installieren:🎜public function handle(Request $request, Closure $next) { // Handle request $method = $request->getMethod(); // Support using HEAD method for checking If-None-Match if ($request->isMethod('HEAD')) { $request->setMethod('GET'); } //Handle response $response = $next($request); $etag = '"'.md5($response->getContent()).'"'; $noneMatch = $request->getETags(); if (in_array($etag, $noneMatch)) { $response->setNotModified(); } $request->setMethod($method); return $response; }
etag
-Middleware verwendet werden. Wenn Sie lernen möchten, wie Middleware funktioniert, oder wenn Sie diese Funktion implementieren möchten, ohne unser Plug-In-Paket zu verwenden, lesen Sie bitte weiter! 🎜🎜SetEtag Middleware🎜🎜Wie Sie vielleicht schon erraten haben, können wir diese Funktion einfach über Middleware implementieren. Laravel
stellt uns tatsächlich eine SetCacheHeaders
-Middleware zum Festlegen des ETag
-Headers zur Verfügung, unterstützt jedoch keine HEAD
-Anfragen. Der Inhalt der SetEtag
-Middleware sieht folgendermaßen aus: 🎜public function handle(Request $request, Closure $next) { // 只有请求方式是 PATCH 并且已经设置了 If-Match 头 if (! ($request->isMethod('PATCH') && $request->hasHeader('If-Match'))) { return $next($request); } // 对同一个点创建新的 GET 请求, // 复制和添加请求头,让中间件能忽略本次请求 $getRequest = Request::create($request->getRequestUri(), 'GET'); $getRequest->headers = $request->headers; $getRequest->headers->set('X-From-Middleware', 'IfMatch'); $getResponse = app()->handle($getRequest); // Get content from response object and get hashes from content and etag $getContent = $getResponse->getContent(); $getEtag = '"'.md5($getContent).'"'; $ifMatch = $request->header('If-Match'); // 比较当前和请求携带的 hash 值 if ($getEtag !== $ifMatch) { return response(null, 412); } return $next($request);
HEAD
-Anfrage verarbeiten, ändern wir sie in eine GET
-Anfrage, um sicherzustellen, dass der angeforderte Inhalt geladen wurde und verschlüsselt werden kann. Danach springen wir zum Inhalt des Antworttextes, der mit der Methode md5()
verschlüsselt wurde. Bevor wir die Antwort zurückgeben, verwenden wir den verschlüsselten hash
-Wert als ETag
-Header und setzen die ursprüngliche Anfragemethode zurück. 🎜🎜IfNoneMatch Middleware 🎜🎜Dies ist eine weitere relativ einfache Methode. Schauen wir uns zunächst den Code an: 🎜public function handle(Request $request, Closure $next) { // Handle request $method = $request->getMethod(); // Support using HEAD method for checking If-None-Match if ($request->isMethod('HEAD')) { $request->setMethod('GET'); } //Handle response $response = $next($request); $etag = '"'.md5($response->getContent()).'"'; $noneMatch = $request->getETags(); if (in_array($etag, $noneMatch)) { $response->setNotModified(); } $request->setMethod($method); return $response; }
这个开头与 SetEtag
中间件相似,将确保我们可以再次处理 HEAD
请求,并根据响应内容生成 hash值。注意这种情况下我们需要将hash值用双引号包裹。双引号包裹 ETag
头,然后在setEtag中间件中 setEtag()
方法自动包裹hash。有了hash值后,我们可以轻松的与 If-None-Match
头进行比较。由于该头可以自动加载无限个hash,并且 getETags()
方法会将它们以数组形式返回,所以我们可以核对新生成的值是否存在于数组中。如果确实有匹配,我们可以在响应中使用 setNotModified()
设置 304
的状态码。
IfMatch 中间件
处理 If-Match
将稍微复杂一些。这个问题归结于:我们需要找到一种方法,用来获取应该更新的当前版本的内容。这可以用多种方式实现。
- 你可以使用 HTTP 客户端对相同资源从外部发起
GET
请求 - 你可以查看当前请求将执行的操作, 而不是调用与之等价的
GET
请求( 例如,调用控制器上的show()
方法) - 或者你可以通过内部发起一个新的
GET
请求。
在构建这个中间件时,我开始尝试使用第二个选项。出于某种原因,这对我来说似乎是最好的选择。我成功地创建了一个完全可以工作的版本,但我对结果并不满意。为了让它工作,我需要做一些假设,预设一些限制,并做了太多的工作,而我只需要创建一个新的请求就可以了。
当我们要发起一个新的请求来获取当前版本资源的时候,代码是下面这样的:
public function handle(Request $request, Closure $next) { // 只有请求方式是 PATCH 并且已经设置了 If-Match 头 if (! ($request->isMethod('PATCH') && $request->hasHeader('If-Match'))) { return $next($request); } // 对同一个点创建新的 GET 请求, // 复制和添加请求头,让中间件能忽略本次请求 $getRequest = Request::create($request->getRequestUri(), 'GET'); $getRequest->headers = $request->headers; $getRequest->headers->set('X-From-Middleware', 'IfMatch'); $getResponse = app()->handle($getRequest); // Get content from response object and get hashes from content and etag $getContent = $getResponse->getContent(); $getEtag = '"'.md5($getContent).'"'; $ifMatch = $request->header('If-Match'); // 比较当前和请求携带的 hash 值 if ($getEtag !== $ifMatch) { return response(null, 412); } return $next($request);
所有这些中间件都将在请求生命周期开始时运行。首先,我们将过滤掉任何非 PATCH
请求或请求头中没有 If Match
的请求。之后,我们将向同一个端点发出一个新的 GET
请求,并从原来的请求中复制请求头,以便新请求可以通过身份验证中间件和其他约束。
使用这个新请求的响应,我们将再次生成一个哈希,以便与发送的哈希进行比较。如果哈希匹配,请求将被中间件允许通过。如果不匹配,将返回状态代码为 412
的请求响应。
通过使用这三个中间件,你可以在你的 Laravel 应用程序中轻松处理 ETag 和条件请求。
软件包:https://github.com/365Werk/etagconditionals
原文地址:https://hergen.nl/caching-your-laravel-api-with-etag-and-conditional-requests
译文地址:https://learnku.com/laravel/t/55539
Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung der Verwendung von ETag und bedingten Headern für das Caching. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Die neuesten Versionen von Laravel 9 und CodeIgniter 4 bieten aktualisierte Funktionen und Verbesserungen. Laravel9 übernimmt die MVC-Architektur und bietet Funktionen wie Datenbankmigration, Authentifizierung und Template-Engine. CodeIgniter4 nutzt die HMVC-Architektur, um Routing, ORM und Caching bereitzustellen. In Bezug auf die Leistung sorgen das auf Dienstanbietern basierende Designmuster von Laravel9 und das leichte Framework von CodeIgniter4 für eine hervorragende Leistung. In praktischen Anwendungen eignet sich Laravel9 für komplexe Projekte, die Flexibilität und leistungsstarke Funktionen erfordern, während CodeIgniter4 für schnelle Entwicklung und kleine Anwendungen geeignet ist.

Vergleichen Sie die Datenverarbeitungsfunktionen von Laravel und CodeIgniter: ORM: Laravel verwendet EloquentORM, das eine relationale Klassen-Objekt-Zuordnung bereitstellt, während CodeIgniter ActiveRecord verwendet, um das Datenbankmodell als Unterklasse von PHP-Klassen darzustellen. Abfrage-Builder: Laravel verfügt über eine flexible verkettete Abfrage-API, während der Abfrage-Builder von CodeIgniter einfacher und Array-basiert ist. Datenvalidierung: Laravel bietet eine Validator-Klasse, die benutzerdefinierte Validierungsregeln unterstützt, während CodeIgniter über weniger integrierte Validierungsfunktionen verfügt und eine manuelle Codierung benutzerdefinierter Regeln erfordert. Praxisfall: Beispiel einer Benutzerregistrierung zeigt Lar

Für Anfänger bietet CodeIgniter eine sanftere Lernkurve und weniger Funktionen, deckt aber die Grundbedürfnisse ab. Laravel bietet einen größeren Funktionsumfang, weist jedoch eine etwas steilere Lernkurve auf. In Bezug auf die Leistung schneiden sowohl Laravel als auch CodeIgniter gut ab. Laravel verfügt über eine umfangreichere Dokumentation und aktive Community-Unterstützung, während CodeIgniter einfacher und leichtgewichtiger ist und über starke Sicherheitsfunktionen verfügt. Im praktischen Fall der Erstellung einer Blogging-Anwendung vereinfacht EloquentORM von Laravel die Datenmanipulation, während CodeIgniter mehr manuelle Konfiguration erfordert.

Laravel – Artisan Commands – Laravel 5.7 bietet eine neue Möglichkeit, neue Befehle zu behandeln und zu testen. Es enthält eine neue Funktion zum Testen von Handwerkerbefehlen und die Demonstration wird unten erwähnt?

Bei der Auswahl eines Frameworks für große Projekte haben Laravel und CodeIgniter jeweils ihre eigenen Vorteile. Laravel ist für Anwendungen auf Unternehmensebene konzipiert und bietet modularen Aufbau, Abhängigkeitsinjektion und einen leistungsstarken Funktionsumfang. CodeIgniter ist ein leichtes Framework, das sich eher für kleine bis mittelgroße Projekte eignet und Wert auf Geschwindigkeit und Benutzerfreundlichkeit legt. Für große Projekte mit komplexen Anforderungen und einer großen Anzahl von Benutzern sind die Leistung und Skalierbarkeit von Laravel besser geeignet. Für einfache Projekte oder Situationen mit begrenzten Ressourcen sind die leichten und schnellen Entwicklungsfunktionen von CodeIgniter idealer.

Für kleine Projekte eignet sich Laravel, für größere Projekte, die starke Funktionalität und Sicherheit erfordern. CodeIgniter eignet sich für sehr kleine Projekte, die geringes Gewicht und Benutzerfreundlichkeit erfordern.

Vergleichen Sie Laravel's Blade und die Twig-Vorlagen-Engine von CodeIgniter und wählen Sie je nach Projektanforderungen und persönlichen Vorlieben: Blade basiert auf der MVC-Syntax, die eine gute Codeorganisation und Vorlagenvererbung fördert. Twig ist eine Bibliothek eines Drittanbieters, die flexible Syntax, leistungsstarke Filter, erweiterten Support und eine Sicherheits-Sandbox bietet.

Laravel – Artisan Console – Das Laravel-Framework bietet drei Haupttools für die Interaktion über die Befehlszeile, nämlich Artisan, Ticker und REPL. In diesem Kapitel wird Artisan ausführlich erläutert.
