PHP Encrypt AES-256-GCM using Phpseclib and Decrypt with Javascript using crypto.subtle

In order to achieve what i wrote as subject, i have this php code:

<?php
require 'vendor/autoload.php';
use phpseclib3CryptAES; // Per l'encryptMessage
use phpseclib3CryptRandom; // Per la generateSharedKey

function generateSharedKey() {
    return base64_encode(Random::string(16));
}
function encryptMessage($messaggio_da_criptare, $chiave) {
    $aes = new AES('gcm');
    $aes->setKey($chiave);
    $iv=base64_encode(openssl_random_pseudo_bytes(12));
    $aes->setNonce($iv);
    $testo_cifrato = $aes->encrypt($messaggio_da_criptare);
    $tag = $aes->getTag();
    $dati_criptati = ['messaggio_criptato_con_tag' => base64_encode($testo_cifrato.$tag),'iv' => $iv];
    return $dati_criptati;
}

$messaggio = "Hello, this is a secret message!";
echo "Messaggio di esempio da criptare: ".$messaggio."<br>";
$chiave = generateSharedKey();
echo "Chiave segreta: ".$chiave."<br>";
$dati_criptati = encryptMessage($messaggio, $chiave);
echo "Messaggio criptato con tag incluso: ".$dati_criptati["messaggio_criptato_con_tag"]."<br>";
echo "IV: ".$dati_criptati["iv"]."<br>";
?>

and this html code

<!DOCTYPE html>
<html>
<script>
var phpkey = "TWw4QCkeZEnXoCDkI1GEHQ==";
var phpiv = "CRKTyQoWdWB2n56f";
var phpmessageencrypted = "7K+HAB7Ch9V4jJ1XJPM0sANXA2ocJok=";

(async () => {
    function _base64ToArrayBuffer(base64) {
        var binary_string = atob(base64);
        var len = binary_string.length;
        var bytes = new Uint8Array(len);
        for (var i = 0; i < len; i++) {
            bytes[i] = binary_string.charCodeAt(i);
        }
        return bytes.buffer;
    }
    async function _importKeyAes(key) {
        return await window.crypto.subtle.importKey("raw",key,{ name: "AES-GCM" },false,["encrypt", "decrypt"]);
    }
    async function decryptMessageSymetric(key, data, iv) {
        var keyArrayBuffer = _base64ToArrayBuffer(key);
        var keyt = await _importKeyAes(keyArrayBuffer);
        var ivt = new TextEncoder().encode(iv);
        var datat = _base64ToArrayBuffer(data);
        var result = await window.crypto.subtle.decrypt({ name: "AES-GCM", iv: ivt, tagLength: 128 },keyt,datat);
        return new TextDecoder().decode(result);
    }
    var result = await decryptMessageSymetric(phpkey, phpmessageencrypted, phpiv); 
    console.log(result);
})();
</script>
</html>type here

The problem is:
If you launch the php script and test the result with an online tool like this:
text
It works and seems that the encryption step is correct.

If you launch the html page and you check with the inspector, with the provided example data it works.

But, if you replace:

var phpkey = "TWw4QCkeZEnXoCDkI1GEHQ=="; var phpiv = "CRKTyQoWdWB2n56f"; var phpmessageencrypted = "7K+HAB7Ch9V4jJ1XJPM0sANXA2ocJok=";

with the php given data, it doesn’t work and browser give the following (and unuseful) error code:
Uncaught (in promise) DOMException: The operation failed for an operation-specific reason
while the online tool report this:

screenshot

I really don’t know what i’m doing wrong. Probably something regarding the KEY and IV, but why they are accepted by the online tool and not by the html/js script?

Thanks for the help.

I’m expecting that it works in a deterministic way.