Когда мне следует использовать атрибут «crossorigin» для «preconnect» <link>?

14

Я хотел бы включить некоторые подсказки ресурсов предварительного соединения на моем сайте, чтобы браузеры могли (например) подключиться к jQuery CDN, прежде чем они действительно увидят тег script, который вызывает CDN. Я не уверен, должен ли я включать атрибут «crossorigin» или каково его значение. Спецификации говорят, в частности,

Чтобы инициировать предварительное соединение, пользовательский агент должен выполнить эти шаги:

[...]

  1. Пусть corsAttributeState будет текущим состоянием crossoriginатрибута содержимого элемента .
  2. Пусть учетные данные будут логическим значением, установленным в true.
  3. Если corsAttributeState имеет значение, Anonymousа origin не равен источнику текущего документа, установите учетные данные в false.
  4. Попытка получить связь с источником и учетными данными .

Я не знаю, как интерпретировать этот алгоритм. Если я предварительно подключусь к CDN, который позволит любому загружать его содержимое без каких-либо учетных данных, какое значение я должен использовать для атрибута «crossorigin»?

bdesham
источник
Связанный: stackoverflow.com/questions/55520102/…
jakub.g

Ответы:

4

Я искал то же самое, и я нашел это

Здесь говорится, что если вы не используете атрибут кросс-происхождения, пользовательский агент просто выполняет поиск DNS, но не устанавливает соединение с конкретным доменом. Таким образом, атрибут crossorigin необходим, если вам нужно предварительно подключиться к кросс-домену, например так:

<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>

Также, если вы хотите отправить некоторые учетные данные в этот конкретный междоменный домен, вы можете установить значение для перекрестного поиска, так как в crossorigin = use-credentialsпротивном случае я думаю, что значение по умолчанию является анонимным.

orangespark
источник
Это наполовину правда. Если используется CORS (как со шрифтами), только запрос DNS будет использоваться с запросом шрифта. (Соединение все еще происходит, но оно не отображается в диаграмме водопада, потому что для запроса CORS должно быть открыто отдельное соединение .) Если вы выбираете сценарий, использование crossoriginаналогичным образом приведет к потере соединения, поскольку должно быть открыто новое соединение, которое не использует CORS.
Майкл Креншоу
2

До сих пор я понимаю использование crossorigin, особенно с точки зрения его значений, anonymousи use-credentialsвы должны использовать crossorigin="use-credentials"в случае:

  • вы используете активы, такие как изображения или видео, которые имеют атрибут crossorigin
  • вы планируете переносить файлы cookie, HTTP-аутентификацию и клиентские SSL-сертификаты между источниками на основе предыдущих взаимодействий агента пользователя с источником.

В дополнение к цитируемой вами документации я получил то и это . Но на самом деле документация вводит в заблуждение и содержит орфографические ошибки: первая вызывает ее use-credentials, вторая - user-credentials.

Во всяком случае, в моем понимании:

  • нет crossoriginна всех равныхcrossorigin="anonymous"
  • crossorigin равно crossorigin="use-credentials"

Может, кто-нибудь меня поправит.

PS : Текущая версия страницы Mozilla для темы означает:

Недопустимое ключевое слово и пустая строка будут обрабатываться как анонимное ключевое слово.

Значит: нет crossoriginвообще crossoriginили crossorigin="use_credentials"все обрабатываются как crossorigin="anonymous".

Евгений
источник
5
Я полагаю, как упоминалось в MDN , по умолчанию (то есть, когда атрибут не указан), CORS вообще не используется. Кроме того, настройка только crossoriginравна crossorigin="anonymous".
Шекспир
1

Это зависит от двух вещей:

  1. Тип загружаемых ресурсов (который определяет, будет ли использоваться CORS)
  2. Использует ли целевой сервер учетные данные для соединений CORS

Для jQuery вы бы не использовалиcrossorigin . Скрипты не входят в число типов ресурсов, которые браузеры используют для загрузки .

Шрифты, с другой стороны, используют CORS.

  • Если страница будет выбирать только те ресурсы, которые используют CORS, включите crossoriginатрибут.
  • Если страница будет получать только ресурсы, которые не используют CORS, опустите crossorigin. Если
  • Если страница будет получать оба вида ресурсов, вам могут потребоваться две подсказки ресурса . (Полное раскрытие, ссылка на мой личный сайт. :-)) Кто-то указал, что вам может не понадобиться две подсказки для HTTP / 2. У меня не было времени, чтобы проверить.

Вот сообщение о переполнении стека, где я столкнулся с той же проблемой.

Я не углублялся, когда необходимы учетные данные CORS. Я не видел пример, где они нужны, так что, скорее всего, вы в безопасности crossorigin(например, `crossorigin =" anonymous ").

Майкл Креншоу
источник
1

Все ответы до сих пор кажутся либо упрощенными, неполными или частично неправильными (тема сложная, вещи смущенно названы и плохо документированы!), Так что вот мое понимание:

Чтобы иметь возможность повторно использовать созданное соединение <link rel=preconnect>, все зависит от того, какой тип контента вы хотите получить, откуда, будет ли запрос отправлять учетные данные браузера (которые могут быть установлены браузером явно или неявно):

Запрос того же происхождения ( example.comзапрашивает субресурс из example.com)

Во preconnect-первых , вообще не нужно ; браузер сохраняет соединение открытым после загрузки страницы в течение достаточно долгого времени. Если необходимо открыть несколько подключений, браузер сам решает, открывать ли и сколько (в зависимости от того, объявляет ли сервер поддержку HTTP / 2 при рукопожатии TLS, настройках браузера и т. Д.)

Подлежит проверке : что если запрос того же источника имеет crossoriginатрибут: используется или игнорируется?

Запрос перекрестного происхождения ( example.comзапрашивает субресурс из another.com)

  • если фактический запрос имеет crossoriginатрибут, явно установленный в HTML ( crossOriginв JS - регистр важен), у предварительного соединения также должен быть его, с тем же значением (возможно, за исключением случаев, когда он не имеет смысла и crossoriginигнорируется - не полностью ясно для мне пока)
  • иначе, если запрос, если для <script type=module>: будет проверено
  • иначе, если запрос и «старая школа» запрос <img>, <style type=stylesheet>, <iframe>, классический и <script>т.д. (инициируемые с помощью HTML или JS) без crossoriginявно указанного , то preconnect не должен иметь crossoriginнабор атрибутов.
  • иначе, если запрос является запросом шрифта кросс-источника , предварительное соединение должно иметьcrossorigin=anonymous
  • иначе, если запрос является кросс-источником fetch или XHR:
    • если это делается в режиме учетных данных (т. е. файлы cookie подключены или используется базовая аутентификация HTTP; в случае выборки это означает credentials !== omit; в случае withCredentials === trueXHR:): предварительное соединение должно иметьcrossorigin=use-credentials
    • если он не в режиме учетных данных: preconnect должен иметь crossorigin=anonymous

В последнем случае (выборка / XHR) перейдите на сетевую панель в Chrome / Firefox devtools, щелкните правой кнопкой мыши запрос и выберите copy as fetchиз выпадающего списка. Это создаст фрагмент JS, который скажет вам, является ли этот запрос CORS-enabled ( "mode"=="cors") и credentialed ( "credentials"=="include"|"same-origin").

Однако обратите внимание, что вышеприведенный трюк не работает правильно для не-XHR / запросов выборки, потому что, например, fetchи <img>использовать разные алгоритмы для установления соединения, как объяснено ранее.

Наконец, в HTML <link ...crossorigin>=== <link ...crossorigin=anonymous>.

Дополнительные заметки и ссылки:

jakub.g
источник