负责的开发人员的HTTP标头


今天,在线是许多人的普遍条件。 我们都购买,交流,阅读文章,寻找有关各种主题的信息。 网络将我们连接到整个世界,但最重要的是,它连接了人们。 我本人已经使用Internet 20年了,八年前当我成为Web开发人员时,与Internet的关系发生了变化。

开发人员将人们联系在一起。
开发人员可以帮助人们。
开发人员给人们机会。

开发人员可以为每个人创建一个网络,但是必须负责任地使用此功能。 最后,重要的是创造可以帮助人们并赋予他们权力的事物。 在本文中,我想谈谈HTTP标头如何帮助您创建更好的产品,以实现Internet上所有用户的最佳工作。

HTTP-超文本传输​​协议


让我们先谈谈HTTP。 HTTP是计算机用于通过Internet请求和发送数据的协议。

当浏览器从服务器请求资源时,它使用HTTP。 该请求包括一组键值对,其中包含信息,例如它可以理解的浏览器版本或文件格式。 这些对称为请求标头。

服务器使用请求的资源进行响应,但还会发送包含有关资源或服务器本身的信息的响应头。

Request: GET https://the-responsible.dev/ Accept: text/html,application/xhtml+xml,application/xml Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,de;q=0.7 ... Response: Connection: keep-alive Content-Type: text/html; charset=utf-8 Date: Mon, 11 Mar 2019 12:59:38 GMT ... Response Body 

如今,HTTP已成为Internet的基础,并提供了许多优化用户体验的方法。 让我们看看如何使用HTTP标头来创建安全且可访问的网络。

网络必须安全


当我在Internet上搜索内容时,我从来没有感到过危险。 但是,我对万维网了解的越多,我就越担心。 您可以阅读黑客如何更改全球CDN库随机站点如何在其访问者的浏览器中挖掘加密货币,以及人们如何通过社会工程学定期访问成功的开源项目 。 这不好。 但是你为什么要关心呢?

如果您今天正在为Web开发,那么不要仅仅编写代码。 如今,在Web开发中,许多人在一个站点上工作。 您可能还会使用很多开源软件。 另外,出于营销目的,您可以包括多个第三方脚本。 数百人提供在您的网站上运行的代码。 开发人员必须在这样的现实环境中工作。

所有这些人和所有源代码可以信任吗?

我认为不应该信任任何第三方代码。 幸运的是,有一些方法可以保护您的网站并使其更加安全。 另外,诸如头盔之类的工具对于例如快速应用可能是有用的

如果要分析站点上运行了多少第三方代码,可以在开发人员面板中查看或尝试“ 请求地图生成器”。

HTTPS和HSTS-确保您的连接安全


安全连接是安全互联网的基础。 如果没有经过 HTTPS的加密请求,您将无法确保站点和访问者之间没有其他请求。 一个人可以快速建立一个公共Wi-Fi网络,并对连接到该网络的任何人发动中间攻击 。 您多久使用一次公共Wi-Fi? 另外,您多久检查一次是否值得信任?

幸运的是,今天TLS证书是免费的 ; HTTPS已成为标准,浏览器仅提供用于安全连接的高级功能,甚至将非HTTPS网站标记为不安全,这有利于该协议的实施。 不幸的是,当我们上网时,我们并不总是安全的。 当有人要打开站点时,他不会在地址栏中输入协议(为什么要这么做?)。 这将导致未加密的HTTP请求。 安全运行的站点将用户重定向到HTTPS。 但是,如果有人拦截了第一个不安全的请求怎么办?

您可以使用HSTS (HTTP严格传输安全性)响应标头来告诉浏览器您的站点仅通过HTTPS运行。

 Strict-Transport-Security: max-age=1000; includeSubDomains; preload 

此标头告诉浏览器您不想使用HTTP请求,然后它将通过安全连接将相同的请求自动应用于相同的源。 如果您尝试通过HTTP打开相同的URL,浏览器将再次使用HTTPS并重定向用户。

如果您以后想再次使用HTTP,则可以配置此选项保持激活状态的时间(以秒为单位)。 如果要启用子域,则可以使用includeSubDomains进行配置。

如果您想尽一切可能使浏览器从不通过HTTP请求您的站点,则还可以设置preload指针并将站点发送到全局列表。 如果您站点的HSTS配置对应于一年的最小max-age期限,并且对子域有效,则可以将其包含在内部浏览器列表中,以用于仅通过HTTPS运行的站点。

您是否曾经想过为什么无法再通过HTTP在浏览器中使用局部环境变量(例如my-site.dev ? 原因恰好在此内部列表中.dev自动包含在此列表中,因为自2019年2月起,它成为了真正的顶级域。

HSTS标头不仅使您的网站更安全,而且加快了工作速度。 想象某人正在访问缓慢的移动连接。 如果第一个请求是通过HTTP发出的,仅是为了接收重定向,则用户可能会在几秒钟内看不到屏幕上的任何内容。 借助HSTS,您可以保存这些秒数,浏览器将自动使用HTTPS。

CSP-明确指出您网站上允许的内容


现在您的站点正在通过安全连接运行,当浏览器开始阻止由于混合内容策略而到达不安全地址的请求时,您可能会遇到问题。 内容安全策略(CSP)标头提供了一种处理这些情况的好方法。 您可以使用提供的HTML中的元元素或通过HTTP标头设置CSP规则集。

 Content-Security-Policy: upgrade-insecure-requests 

upgrade-insecure-requests指针使浏览器神奇地将所有HTTP请求转换为HTTPS请求。

但是,CSP不限于所使用的协议。 它提供详细的方法来确定您的站点上允许哪些资源和活动。 例如,您可以指定应执行哪些脚本或从何处下载图像。 如果不允许某些操作,浏览器将阻止此操作并防止对您的网站进行潜在的攻击。



在撰写本文时,CSP有24种不同的配置选项。 它们的范围从脚本到样式表再到服务人员。



您可以在MDN上找到完整的评论

使用CSP,您可以指定站点应包含的内容以及不应该包含的内容。

 Content-Security-Policy: default-src 'self'; script-src 'self' just-comments.com www.google-analytics.com production-assets.codepen.io storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: images.contentful.com images.ctfassets.net www.gravatar.com www.google-analytics.com just-comments.com; font-src 'self' data:; connect-src 'self' cdn.contentful.com images.contentful.com videos.contentful.com images.ctfassets.net videos.ctfassets.net service.just-comments.com www.google-analytics.com; media-src 'self' videos.contentful.com videos.ctfassets.net; object-src 'self'; frame-src codepen.io; frame-ancestors 'self'; worker-src 'self'; block-all-mixed-content; manifest-src 'self' 'self'; disown-opener; prefetch-src 'self' 

以上规则是针对我的个人站点的,如果您认为此CSP定义示例非常复杂,那么您绝对正确。 我第三次尝试实施此工具包,然后再次部署并回滚,因为它多次破坏了站点。 但是有更好的方法。

为避免黑客入侵您的网站,CSP还提供了仅报告模式。

 Content-Security-Policy-Report-Only: default-src 'self'; ... report-uri https://stefanjudis.report-uri.com/r/d/csp/reportOnly 

使用Content-Security-Policy-Report-Only模式,浏览器只记录将被阻止的资源,而不是实际阻止它们。 通过此报告机制,您可以验证和配置规则集。

标头Content-Security-PolicyContent-Security-Policy-Report-Only提供了一种确定发送违规report-uri和日志记录信息的端点的方法( report-uri )。 您可以配置日志服务器,并使用发送的日志信息来配置CSP规则,直到可以发送为止。

建议的过程如下:首先在报告模式下运行CSP,以实际流量分析传入的违规,只有在未检测到对受控资源的违规时才将其打开。

如果您正在寻找可以帮助您处理这些杂志的服务,我建议您使用Report URI ,它对我有很大帮助。

CSP的一般实施


如今,浏览器很好地支持 CSP,但不幸的是,没有很多站点使用它。 为了查看有多少站点使用CSP交付内容,我向HTTParchive发送了一个请求,发现只有6%的站点使用了此策略。 我认为我们可以使Internet更加安全,并保护我们的用户免于不经意间 开采加密货币



网络必须可访问。


在撰写本文时,我正使用快速的家庭Wi-Fi连接坐在相对较新的MacBook前面。 开发人员通常会忘记这种情况对于我们大多数用户而言并不是标准的。 访问我们网站的人们使用旧电话和可疑的连接。 繁重且拥挤的网站上有数百个查询,给他们留下了不好的印象。

这不只是印象。 人们根据自己的住所支付不同的交通流量 。 想象您正在创建一家医院的网站。 有关它的信息至关重要,可以挽救生命。 如果医院网站上的页面大小为5 MB,那么它不仅会运行缓慢,而且对于最需要它的人来说可能太昂贵了。 与非洲的价格相比,欧洲或美国的5兆字节流量的价格可以忽略不计。 开发人员负责使所有人都能访问该网页。 这项责任包括提供正确的资源,选择正确的工具(您真的需要一个JS框架进行登陆吗?)以及避免提出请求。

缓存控制-避免对不可变资源的请求


今天,一个站点可以包含数百种资源,从CSS到脚本和图像。 Cache-Control ,开发人员可以指定资源应被视为“新鲜”的时间,并且可以从浏览器缓存中返回。

 Cache-Control: max-age=30, public 

通过正确配置Cache-Control ,可以保留数据传输,并且可以在一定秒数( max-age )内使用浏览器缓存中的文件。 在这段时间之后,浏览器必须重新检查缓存的资源。

但是,如果访问者刷新页面, 浏览器将以任何方式重新检查它,包括指向资源的链接,以确保缓存的数据仍然有效。 服务器以标头304进行响应,以表示已缓存的数据仍然有效,或者以标头200进行响应,以发送更新的数据。 这使您可以保存传输的数据,但不必发出请求。

这是immutable功能发挥作用的地方。

不可变-永远不会两次请求资源


在现代的前端应用程序中,CSS和脚本文件通常具有唯一的名称,例如styles.123abc.css 。 该文件的名称取决于内容。 当您更改文件内容时,它们的名称也会更改。

这些独特的文件可能会永远被缓存,包括在用户刷新页面时。 immutable可能会阻止浏览器在特定时间间隔内重新检查资源。 这对于具有校验和的对象非常重要,并有助于避免重复的验证请求。

 Cache-Control: max-age=31536000, public, immutable 

实现最佳缓存非常困难,尤其是浏览器缓存不是很直观,因为它具有多种配置。 我建议您阅读以下材料:


接受编码-最大压缩(最小压缩)


借助Cache control我们可以保存请求并减少通过网络重复传输的数据量。 我们不仅可以保存请求,还可以减少传输的内容。

提供资源后,开发人员应注意发送尽可能少的数据。 对于HTML,CSS和JavaScript等文本资源,压缩在保存传输的数据中起着重要的作用。

当今最流行的压缩方法是GZIP。 服务器具有足够的功能来动态压缩文本文件并在请求时提供压缩数据。 但是GZIP不再是最佳选择。

如果查看浏览器生成的对文本文件(例如HTML,CSS和JavaScript)的请求,并分析标题,则会发现其中包含accept-encoding

 Accept-Encoding: gzip, deflate, br 

该标头告诉服务器它了解哪种压缩算法。 鲜为人知的br参数代表Brotli压缩 ,并用于人流量大的网站,例如Google和Facebook。 要使用Brotli,您的站点必须通过HTTPS运行。

创建这种压缩算法时要考虑到较小的文件大小。 如果您尝试在本地设备上手动压缩文件,则会发现Brotli的压缩效果确实好于GZIP。



您可能已经听说Brotli压缩速度较慢。 原因是Brotli具有11种压缩模式,默认情况下会获得选择最小文件的压缩模式,这会延长过程。 另一方面,GZIP具有9种模式,并且默认情况下选择了一种,同时考虑了压缩速度和文件大小。 因此,默认情况下,Brotli模式不适合即时压缩,但是如果更改模式,则可以以与GZIP相同的速度压缩小文件。 您可以动态地使用它进行压缩,并可以将其视为GZIP的潜在替代品,以支持浏览器。

另外,如果要尽可能多地保存文件,则可以忽略动态压缩,并使用zopfli和Brotli 文件进行静态维护预先生成优化的GZIP文件

如果您想了解有关Brotli压缩及其与GZIP的比较的更多信息,Akamai的员工已对该主题进行了广泛的研究

接受并接受CH-为用户提供个人资源


优化文本资源对于节省千字节非常重要,但是诸如图像之类的较重资源可以保存更多数据呢?

接受-以正确的格式维修图像


浏览器不仅向我们展示了他们了解哪种压缩算法。 当浏览器请求图像时,它还提供有关它可以理解的文件格式的信息。

 Accept: image/webp, image/apng, image/*,*/*;q=0.8 

几年来,人们一直在围绕一种新的图像格式进行斗争,但最终赢得了webp。 Webp是Google发明的一种图像格式 ,现在这种格式的支持非常重要。

使用此请求标头,即使浏览器请求image.jpg ,开发人员也可以发送webp图像,从而减小文件大小。 迪恩·休姆(Dean Hume)就如何应用此书撰写了很好的指南 。 太酷了!



Accept-CH-提供合适大小的图像


您还可以为支持此功能的浏览器启用客户端提示 。 客户端提示是一种告诉浏览器发送有关查看区域宽度,图像宽度甚至网络条件(例如RTT(传输和确认时间)和连接类型,例如2g )的附加信息的方法。

您可以通过添加meta元素来激活提示:

 <meta http-equiv="Accept-CH" content="Viewport-Width, Downlink"> <meta http-equiv="Accept-CH-Lifetime" content="86400"> 

或通过在原始HTML请求中设置标题:

 Accept-CH: Width, Viewport-Width Accept-CH-Lifetime: 100 

在随后的请求中,浏览器将在特定时间段内开始发送其他信息(以秒为单位的Accept-CH-Lifetime ),这可以帮助开发人员在不更改HTML的情况下使图像适应用户条件。

例如,有关更多信息,例如服务器端图像的宽度,可以为图像提供sizes属性,以向浏览器提供有关这些图像的外观的其他信息。

 <!-- this images is laid over the full width | 100 viewport width --> <img class="w-100" src="/img/header.jpg" alt="" sizes="100vw"> 

接收到Accept-CH响应标头和具有sizes属性的图像后,浏览器将在图像请求中包含viewport-widthwidth标头,向您显示最适合的图像。



具有受支持的格式和图像大小,您可以发送经过修改的数据,而不必记录不可靠的图像元素,而只需注意文件格式和大小,如下所示。

 <pictur> <!-- serve WebP to Chrome, Edge, Firefox and Opera --> <source media="(min-width: 50em)" sizes="50vw" srcset="/image/thing-200.webp 200w, /image/thing-400.webp 400w, /image/thing-800.webp 800w, /image/thing-1200.webp 1200w, /image/thing-1600.webp 1600w, /image/thing-2000.webp 2000w" type="image/webp"> <source sizes="(min-width: 30em) 100vw" srcset="/image/thing-crop-200.webp 200w, /image/thing-crop-400.webp 400w, /image/thing-crop-800.webp 800w, /image/thing-crop-1200.webp 1200w, /image/thing-crop-1600.webp 1600w, /image/thing-crop-2000.webp 2000w" type="image/webp"> <!-- serve JPEG to others --> <surce media="(min-width: 50em)" sizes="50vw" srcset="/image/thing-200.jpg 200w, /image/thing-400.jpg 400w, /image/thing-800.jpg 800w, /image/thing-1200.jpg 1200w, /image/thing-1600.jpg 1600w, /image/thing-2000.jpg 2000w"> <surce sizes="(min-width: 30em) 100vw" srcset="/image/thing-crop-200.jpg 200w, /image/thing-crop-400.jpg 400w, /image/thing-crop-800.jpg 800w, /image/thing-crop-1200.jpg 1200w, /image/thing-crop-1600.jpg 1600w, /image/thing-crop-2000.jpg 2000w"> <!-- fallback for browsers that don't support picture --> <img src="/image/thing.jpg" width="50%"> </pictur> 

如果可以访问视口的宽度和图像大小,则可以将调整资源大小的逻辑放在服务器的最前端。

但是,请记住,不应仅因为具有图像的确切宽度而创建任何宽度的图像。 发送特定大小范围( image-200image-300... )的image-300有助于使用CDN缓存并节省计算时间。

此外,借助服务人员等现代技术,您甚至可以直接在客户端中拦截和修改请求,以提供最佳的图像文件。 启用客户端工具提示后,服务人员就可以访问布局信息,并且与图像API(例如Cloudinary)结合使用您可以直接在浏览器中配置图像url,以接收正确大小的图像。

如果您正在寻找有关客户提示的更多详细信息,则可以阅读Jeremy WagnerIlya Grigorik撰写的有关此主题的文章。

网络一定要小心


由于我们每个人每天都在网络上花费很多时间,因此我认为非常重要的最后一个方面-网络必须小心。

预载-减少等待时间


作为开发人员,我们重视用户的时间。 没有人愿意浪费时间。 , . , , .

: , , . , HTML . , , . .

Rel=preload , .

HTML-:

 <link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin="anonymous"> 

:

 Link: </font.woff2>; rel=preload; as=font; no-push 

, , , , . .

:

  • , .
  • preload , prefetch preconnect.

Feature-Policy —


, . .

. , . . , , — .

, , ? , ?

Feature-Policy. , , , , .

 Feature-Policy: vibrate 'none'; geolocation 'none' 

. , , , .

 <iframe allow="camera 'none'; microphone 'none'"> 

Feature-Policy , , , . , . .



MDN.

, — push-. , Feature-Policy push- , . , GitHub.

feature policy , , , , .


, . , «HTTP- — » .

, — . , , , … . , , , -, , - .

Source: https://habr.com/ru/post/zh-CN450816/


All Articles