11

I'm trying to use the wp_register_script and wp_enqueue_script FUNCTION on WordPress to enqueue a script, which has two attributes: "integrity" and "crossorigin".

Normally I use PHP and my code looks like:

wp_register_script('jquery', 'http' . ($_SERVER['SERVER_PORT'] == 443 ? 's' : '') . '://code.jquery.com/jquery-3.1.1.slim.min.js', false, null);
wp_enqueue_script('jquery');

With any other script. The wp_register_script takes five parameters (in this case four) $handle, $src, $deps, $ver ($media). I'm wondering where I can add the two attributes. I've already tried:

wp_register_script('jquery', 'http' . ($_SERVER['SERVER_PORT'] == 443 ? 's' : '') . '://code.jquery.com/jquery-3.1.1.slim.min.js'.'integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n"', false, null);
    wp_enqueue_script('jquery');

But it didn't work.

Anyone who had the same problem? This is the original script from bootstrap 4, which also has bootstrap and tether with the same attributes (integrity and crossorigin) so, since it is pretty new, any kind of help will be very appreciated.

7 Answers7

23

I just cracked this by accident. I've had to use conditionals on some CSS files for ancient Internet Explorer versions and figured I may as well try putting an array in the same wp_script_add_data function that I used. It works!

    wp_register_script('jquery3', 'https://code.jquery.com/jquery-3.3.1.min.js', array(), '3.3.1', true); // jQuery v3
    wp_enqueue_script('jquery3');
    wp_script_add_data( 'jquery3', array( 'integrity', 'crossorigin' ) , array( 'sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=', 'anonymous' ) );

Reference: https://developer.wordpress.org/reference/functions/wp_script_add_data/#parameters

For completeness: If adding jQuery v3, you also need Migrate v3: http://jquery.com/download/

cherryaustin
  • 376
  • 2
  • 8
  • 8
    It appears this solution unfortunately doesn't work any more. `wp_script_add_data` appears to only work for specifying "conditional" wrappers for scripts now. (WP 5.1, PHP 7.2.15) – RalphORama Mar 07 '19 at 06:35
17

You can use the script_loader_tag hook (the main part is actually not my code, but I honestly don't remember where I got it, probably somewhere here on SO or WP Stack Exchange):

add_filter( 'script_loader_tag', 'add_attribs_to_scripts', 10, 3 );
function add_attribs_to_scripts( $tag, $handle, $src ) {

// The handles of the enqueued scripts we want to defer
$async_scripts = array(
    'jquery-migrate',
    'sharethis',
);

$defer_scripts = array( 
    'contact-form-7',
    'jquery-form',
    'wpdm-bootstrap',
    'frontjs',
    'jquery-choosen',
    'fancybox',
    'jquery-colorbox',  
    'search'
);

$jquery = array(
    'jquery'
);

if ( in_array( $handle, $defer_scripts ) ) {
    return '<script src="' . $src . '" defer="defer" type="text/javascript"></script>' . "\n";
}
if ( in_array( $handle, $async_scripts ) ) {
    return '<script src="' . $src . '" async="async" type="text/javascript"></script>' . "\n";
}
if ( in_array( $handle, $jquery ) ) {
    return '<script src="' . $src . '" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous" type="text/javascript"></script>' . "\n";
}
return $tag;
} 
HynekS
  • 1,199
  • 1
  • 11
  • 22
3

This is the correct syntax:

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js" integrity="sha256-T0Vest3yCU7pafRw9r+settMBX6JkKN06dqBnpQ8d30=" crossorigin="anonymous"></script>

"integrity" and "crossorgin" are not part of the URL. They are part of the script tag.

Unfortunately Wordpress can not handle attributes on enqueued scripts at the moment.
But they working on it... Status: needs-testing :-)
=> Ticket 22249 / Wordpress Core

MadMonday
  • 39
  • 2
0

Thanks for all the postings, they really helped. I did roll my own version to give it some structure and make it easier to read and update. Use enqueue as normal, use script for CSS files with a false tag at the end so that it loads at the top. Though it can probably be simplified somewhat.

add_filter('script_loader_tag', 'add_attributes_to_script', 10, 3); 

function add_attributes_to_script( $tag, $handle, $src ) {

        $scripts_to_load = array (

            (0) => Array
              (
                ('name') => 'popper_min_js',
                ('type') => '<script type="text/javascript" src="',         
                ('integrity') => 'sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49',
                ('close') => '></script>'
              ),

             (1) => Array
               (
                ('name') => 'bootstrap_min_js', 
                ('type') => '<script type="text/javascript" src="',
                ('integrity') => 'sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T',
                ('close') => '></script>'
               )
        );  

        $key = array_search($handle, array_column($scripts_to_load, 'name'));

        if ( FALSE !== $key){

            $tag = $scripts_to_load[$key]['type'] . esc_url($src) . '" integrity="' . $scripts_to_load[$key]['integrity'] .'" crossorigin="anonymous"' . $scripts_to_load[$key]['close'] . "\n";

        }
        return $tag;
    }
wpNewby
  • 1
  • 3
  • You really shouldn't use script loading for .css, it'll screw up many (if not all,) caching plugins. – Athoxx Oct 30 '18 at 12:15
0

This is well explained here:

For each enqueued script you need to add a filter which adds proper attributes;

/**
* load custom JS
*/
add_action('wp_enqueue_scripts', function() {
    wp_enqueue_style('jquery', 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js', [], null);

    add_filter('style_loader_tag', __NAMESPACE__ . '\\add_jquery_sri', 10, 2); 
});
 
/**
* add SRI attributes to jQuery style loader element

* @param string $html
* @param string $handle
* @return string
*/
function add_jquery_sri($html, $handle) {
    if ($handle === 'jQuery') {
        $html = str_replace(' />', ' integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous" />', $html);
    }
 
    return $html;
}

URL & hash taken from https://cdnjs.com/libraries/jquery All praise to the authors!

emendelski
  • 206
  • 2
  • 8
-1

You can add a CDN with integrity with Crossorigin by using add_action :

function add_jquery(){
echo '<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256- 
 QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>';
 }

 add_action( 'wp_head', 'add_jquery' );
tom hikari
  • 124
  • 3
-2

By jQuery,

jQuery( function( $ ) {
    $( document ).ready(function() {
        var strapatt = document.getElementById('bootstrap-css');
        strapatt.setAttribute("integrity", "sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb");
        strapatt.setAttribute("crossorigin", "anonymous");
    });
});