wp_add_crossorigin_attributes()WP 7.1.0

Добавляет crossorigin="anonymous" к HTML-тегам в переданном HTML коде.

Атрибут crossorigin="anonymous" указывает браузеру загрузить внешний ресурс через CORS без передачи учётных данных: cookies, HTTP-аутентификации и клиентских сертификатов. Это позволяет безопасно использовать ресурс с другого домена.

Аттрибут будет добавлен толкьо к тегам, которые загружают ресурсы с другого источника. Если внешние ресурсы не найдены, HTML остаётся без изменений.

Обрабатывает следующие теги и атрибуты:

  • <audio src>
  • <link href>
  • <script src>
  • <video src> и <video poster>
  • <source src> внутри <audio> или <video>

Для внешнего ресурса из <source> атрибут добавляется к родительскому <audio> или <video>. Теги <img> не обрабатываются.

Если тег уже содержит атрибут crossorigin, функция не изменяет его.

Внутренними считаются URL, которые начинаются с результата site_url() или символа /.

Функция не разбирает URL на протокол, домен и порт. Поэтому:

  • относительный URL без начального слеша, например assets/app.js, будет считаться внешним.
  • а URL вида //cdn.example.com/app.js, наоборот, будет внутренним.

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

Работает на основе: WP_HTML_Tag_Processor()

Хуков нет.

Возвращает

Строку.

  • строку — обработанный HTML.

Использование

wp_add_crossorigin_attributes( $html ): string;
$html(string) (обязательный)
HTML, в котором нужно добавить атрибуты crossorigin.

Примеры

#1 Добавление атрибутов внешним ресурсам

В оба тега будет добавлен атрибут crossorigin="anonymous".

$html = '
	<link rel="stylesheet" href="https://cdn.example.com/style.css">
	<script src="https://cdn.example.com/app.js"></script>

	<script src="/foo/bar.js"></script>
	<script src="foo/bar.js"></script>
';

echo wp_add_crossorigin_attributes( $html );

Получим:

<link crossorigin="anonymous" rel="stylesheet" href="https://cdn.example.com/style.css">
<script crossorigin="anonymous" src="https://cdn.example.com/app.js"></script>

<script src="/foo/bar.js"></script>
<script crossorigin="anonymous" src="foo/bar.js"></script>

#2 Обработка элемента source

Атрибут crossorigin="anonymous" будет добавлен к тегу <video>, а не к вложенному <source>.

$html = '
	<video controls>
		<source src="https://cdn.example.com/video.mp4" type="video/mp4">
	</video>
';

echo wp_add_crossorigin_attributes( $html );

Список изменений

С версии 7.1.0 Введена.

Код wp_add_crossorigin_attributes() WP 7.1

function wp_add_crossorigin_attributes( string $html ): string {
	$site_url = site_url();

	$processor = new WP_HTML_Tag_Processor( $html );

	// See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin.
	$cross_origin_tag_attributes = array(
		'AUDIO'  => array( 'src' ),
		'LINK'   => array( 'href' ),
		'SCRIPT' => array( 'src' ),
		'VIDEO'  => array( 'src', 'poster' ),
		'SOURCE' => array( 'src' ),
	);

	while ( $processor->next_tag() ) {
		$tag = $processor->get_tag();

		if ( ! isset( $cross_origin_tag_attributes[ $tag ] ) ) {
			continue;
		}
		$crossorigin = $processor->get_attribute( 'crossorigin' );
		if ( null !== $crossorigin ) {
			continue;
		}

		if ( 'AUDIO' === $tag || 'VIDEO' === $tag ) {
			$processor->set_bookmark( 'audio-video-parent' );
		}

		$processor->set_bookmark( 'resume' );

		$sought = false;

		$is_cross_origin = false;

		foreach ( $cross_origin_tag_attributes[ $tag ] as $attr ) {
			$url = $processor->get_attribute( $attr );
			if ( is_string( $url ) && ! str_starts_with( $url, $site_url ) && ! str_starts_with( $url, '/' ) ) {
				$is_cross_origin = true;
			}

			if ( $is_cross_origin ) {
				break;
			}
		}

		if ( $is_cross_origin ) {
			if ( 'SOURCE' === $tag ) {
				$sought = $processor->seek( 'audio-video-parent' );

				if ( $sought ) {
					$processor->set_attribute( 'crossorigin', 'anonymous' );
				}
			} else {
				$processor->set_attribute( 'crossorigin', 'anonymous' );
			}

			if ( $sought ) {
				$processor->seek( 'resume' );
				$processor->release_bookmark( 'audio-video-parent' );
			}
		}
	}

	return $processor->get_updated_html();
}