Уменьшение негативного эффекта CORS для повышения производительности

Совместное использование ресурсов между источниками (CORS) - это соглашение между веб-браузерами и веб-серверами из разных источников. Это соглашение позволяет серверам решать, к каким ресурсам разрешен доступ за пределами размещенного домена / субдомена, и инструктировать браузеры соблюдать правила.

Например, вы столкнетесь с CORS, если ваше веб-приложение размещено на myapp.com и обращается к API на api.myapp.com из внешнего интерфейса.

Хотя наличие CORS важно для целей безопасности, большинство разработчиков не замечают его влияния на производительность приложений.

Каждый раз, когда вы делаете HTTP-запрос от внешнего интерфейса к другому домену, браузер отправляет еще один HTTP-запрос перед этим, последовательно, чтобы убедиться, что сервер его предоставляет.

Этот дополнительный запрос называется запросом предварительной проверки, и в большинстве случаев он вызывает значительную задержку во времени ответа, влияя на производительность веб-приложения.

Итак, давайте узнаем, как мы можем обойти предварительный запрос или сократить время ответа, чтобы повысить производительность наших веб-приложений.

1. Предпечатное кэширование с использованием браузера

Как я упоминал ранее, запрос предварительной проверки влияет на производительность приложения. Скорее всего, будет отправлено много предпечатных запросов, в зависимости от количества вызовов API, выполняемых вашим интерфейсом.

Как решение, предварительное кэширование - один из часто используемых методов для уменьшения воздействия. Концепция, лежащая в основе этого, проста.

Кэш предварительной проверки ведет себя аналогично любому другому механизму кэширования. Всякий раз, когда браузер делает запрос предварительной проверки, он сначала проверяет кеш предварительной проверки, чтобы узнать, есть ли ответ на этот запрос. Если браузер находит ответ, он не отправляет запрос предварительной проверки на сервер, а вместо этого использует кешированный ответ. Браузер отправит запрос предварительной проверки только в том случае, если в кеше предварительной проверки нет ответа.

Заголовок ответа Access-Control-Max-Age указывает, как долго результат может храниться в кеше браузера.

На приведенных выше диаграммах показано поведение браузера с кешем предварительной проверки (первый запрос) и без кеша предварительной проверки (второй запрос).

2. Кэширование на стороне сервера с использованием прокси, шлюзов или балансировщиков нагрузки.

В предыдущем методе мы говорили о подходе к кэшированию запросов Preflight в браузерах, а теперь мы переходим к кешированию на стороне сервера.

Хотя этот метод не специализируется на кэшировании предпечатных запросов, мы можем использовать механизм кэширования по умолчанию прокси, шлюзов или даже CDN, таких как AWS CloudFront, для уменьшения задержки предпечатных запросов.

Идея состоит в том, чтобы сократить время ответа на запрос предварительной проверки за счет уменьшения расстояния, на которое проходит предварительная проверка.

Например, возьмем AWS CloudFront CDN, который также действует как прокси. Он использует концепцию, называемую периферийными местоположениями (ближе к местоположению браузера пользователя приложения, чем исходный сервер) для перехвата HTTP-запросов.

Здесь можно указать кэшировать ответ Preflight рядом с граничным местоположением, даже не обращаясь к исходному серверу.

Совет: Поделитесь и повторно используйте свои перехватчики React для извлечения данных с помощью Bit (Github).

Bit часто используется для совместного использования компонентов пользовательского интерфейса React в веб-проектах, но нет абсолютно никаких причин, по которым вы также не должны делиться своими хуками React.

Создайте свои высокооптимизированные ловушки для выборки данных и поделитесь ими с Bit для повторного использования в ваших приложениях.

3. Избегайте использования прокси, шлюзов или балансировщиков нагрузки.

Если мы сможем обслуживать как интерфейс, так и серверную часть через один и тот же домен, мы сможем полностью избежать запросов предварительной проверки, поскольку в CORS нет необходимости.

Предположим, вы разрабатываете веб-приложение локально, и интерфейс работает на http: // localhost: 4200, а серверная часть - на http: // localhost: 3000 / api.

Как вы, возможно, уже знаете, необходимо включить CORS в вашем серверном интерфейсе для связи между этими двумя. Но вы можете легко избежать этого, используя простую конфигурацию прокси в вашем интерфейсе, чтобы сопоставить ваш интерфейс и бэкэнд.

Вам просто нужно определить конфигурацию прокси для пересылки любых запросов, поступающих по пути /api, на http://localhost:3000. Затем вы можете получить доступ к своему внутреннему API, используя тот же домен и порт, которые используются для внешнего интерфейса (http: // localhost: 4200 / api /…), и браузер не будет отправлять какие-либо запросы предварительной проверки, поскольку нет необходимости в CORS. .

Аналогичным образом, когда дело доходит до производственных сред, вы можете использовать шлюзы API, балансировщики нагрузки, прокси или сети CDN, такие как NGINX, Traefik, AWS CloudFront, AWS Application Load Balancer, Azure Application Gateway для выполните базовую конфигурацию маршрута за вас.

4. Простые запросы

Другой способ избежать запросов предварительной проверки - использовать простые запросы. Предварительные запросы не являются обязательными для простых запросов, и согласно спецификации w3c CORS мы можем пометить HTTP-запросы как простые запросы, если они соответствуют следующим условиям.

  • Метод запроса должен быть GET, POST или HEAD.
  • Разрешено только ограниченное количество заголовков, включая Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width и Width.
  • Хотя заголовок Content-Type разрешен, он должен содержать только типы значений _17 _, _ 18_ и text/plain.

Теперь вам должно быть интересно, почему мы не всегда используем эти простые запросы?

Ответ на этот вопрос также прост. Эти ограничения слишком жесткие для современных веб-приложений, и мы не можем ограничить себя этими рамками и предоставлять лучшие решения для клиентов. Например, заголовки авторизации не разрешены в простых запросах, и в настоящее время мы используем заголовки авторизации почти во всех HTTP-запросах.

Итак, если вы собираетесь использовать простой запрос, вам следует быть предельно осторожным в отношении требований вашего приложения.

Последние мысли

Я надеюсь, что теперь вы понимаете методы, которыми мы можем следовать, чтобы улучшить или избежать времени отклика CORS Preflight. Однако, прежде чем использовать эти методы, вы должны хорошо разбираться в CORS и причинах его создания. Обладая этим пониманием и исходя из требований проекта, вы сможете решить, собираетесь ли вы использовать CORS или нет.

Исходя из своего опыта, я бы посоветовал вам использовать CORS только в случае необходимости, потому что мы можем сэкономить много времени на разработку, одновременно уменьшив задержку наших проектов, разрешив доступ из одного источника для вашего внутреннего API. Вы можете легко использовать конфигурацию прокси, шлюз API или балансировщик нагрузки, чтобы свести к минимуму проблемы в таких ситуациях.

Но есть сценарии, в которых нельзя избежать CORS. В этих ситуациях вы можете легко воспользоваться механизмами кэширования браузера или кэширования на стороне сервера, чтобы минимизировать время отклика. Я уверен, что ваше веб-приложение получит преимущество перед производительностью.

Поэтому я предлагаю вам опробовать эти методы в своем следующем веб-приложении, чтобы почувствовать разницу.

Спасибо за чтение!!!

Учить больше