Problem loading external scripts like jQuery
Asked Answered
R

4

19

I'm facing a problem since this morning with webapps deployed with Apps Script that used to works fine previously. Of course no changes has been made to justify this problem.

External scripts are not loaded from the HTML side, and a new error arise in the console.

In order to have a reproducible example:

Code.gs

function doGet() {

  var template = HtmlService.createTemplateFromFile('index');

  return template.evaluate()
                .setTitle('TEST')
                .addMetaTag('viewport', 'width=device-width, initial-scale=1')
                .setSandboxMode(HtmlService.SandboxMode.IFRAME)
}

index.html:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  </head>
  <body>
        <div id="title">Hello</div>
  </body>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

  <script>
    window.onload = function() {

      console.log('loaded');
      console.log($('#title').html());

    }
  </script>
</html>

Results in the console:

[ERROR] This document requires 'TrustedHTML' assignment. (jquery.min.js:2)

[ERROR] Uncaught TypeError: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment. (jquery.min.js:2)

[LOG] loaded

[ERROR] Uncaught ReferenceError: $ is not defined

The source problem appears to be the <script src='' loading jQuery. But I didn't notice any troubleshoot coming from Google, is it a new restriction for Apps Script?

Screenshots: projet/console

Error Sources

Network + CSP

Rosetta answered 28/11, 2023 at 13:37 Comment(3)
web.dev/articles/trusted-typesPains
I had a similar problem but I found that my browser did not get updated properly and once I completed the update it now works perfectly. So I'd try to update the browswer and make sure it complete before wasting time on difficult solutions. It did force me to take a look at trustedHTML though.Portecochere
perhaps your browser updated and now requires you sort of xray and handle any string for js shenanigans before assigning to innerHTML. might be able to circumvent thisFlatfish
B
7

As per the Google Issue Tracker, here's a workaround to put in the very top of your HTML <head>:

<script>
  if (window.trustedTypes && window.trustedTypes.createPolicy) {
    window.trustedTypes.createPolicy('default', {
      createHTML: string => string,
      createScriptURL: string => string,
      createScript: string => string,
    });
  }
</script>
Benzvi answered 28/11, 2023 at 16:23 Comment(3)
"As per the Google Issue Tracker" - please edit your answer to link the issue you are referring to.Cholecystitis
The issue tracker reports that the issue has been fixed, and that this workaround is no longer needed (however, you may need to clear the browser cache).Whitted
It looks like you included code from somewhere else. If you're using someone else's work without giving them credit, that constitutes plagiarism, which is not welcome on Stack Exchange. To fix it, edit to make sure you do ALL the following: 1.Include a link to the source, 2. Mention the author's name, and 3. Quote the copied content. For more details, see referencing help and this FAQ.Mop
M
12

I've observed that the issue seems to be related to recent changes in the Content Security Policy (CSP) by Google, particularly impacting the use of jQuery in AppScript. This issue has been affecting various developers, and you can find more details and ongoing discussions on the Google Issue Tracker here: Google Issue Tracker - CSP & jQuery Issue.

From what I've found, this problem appears to be specific to Chromium-based browsers. In environments like Chrome and Edge, including their incognito modes, jQuery fails to function properly. However, I found that Firefox does not encounter this issue and works as expected.

This browser-specific behavior suggests a workaround: if you're experiencing problems with jQuery in your AppScript projects on Chromium-based browsers, try switching to Firefox as a temporary solution until a more permanent fix is implemented by Google.

EDIT: found the following workaround. Put this in the very top of your HTML <head>.

<script>
  if (window.trustedTypes && window.trustedTypes.createPolicy) {
    window.trustedTypes.createPolicy('default', {
      createHTML: string => string,
      createScriptURL: string => string,
      createScript: string => string,
    });
  }
</script>
Milldam answered 28/11, 2023 at 16:2 Comment(1)
It looks like you included code from somewhere else. If you're using someone else's work without giving them credit, that constitutes plagiarism, which is not welcome on Stack Exchange. To fix it, edit to make sure you do ALL the following: 1.Include a link to the source, 2. Mention the author's name, and 3. Quote the copied content. For more details, see referencing help and this FAQ.Mop
B
7

As per the Google Issue Tracker, here's a workaround to put in the very top of your HTML <head>:

<script>
  if (window.trustedTypes && window.trustedTypes.createPolicy) {
    window.trustedTypes.createPolicy('default', {
      createHTML: string => string,
      createScriptURL: string => string,
      createScript: string => string,
    });
  }
</script>
Benzvi answered 28/11, 2023 at 16:23 Comment(3)
"As per the Google Issue Tracker" - please edit your answer to link the issue you are referring to.Cholecystitis
The issue tracker reports that the issue has been fixed, and that this workaround is no longer needed (however, you may need to clear the browser cache).Whitted
It looks like you included code from somewhere else. If you're using someone else's work without giving them credit, that constitutes plagiarism, which is not welcome on Stack Exchange. To fix it, edit to make sure you do ALL the following: 1.Include a link to the source, 2. Mention the author's name, and 3. Quote the copied content. For more details, see referencing help and this FAQ.Mop
L
4

Your error suggests that the URL does not comply to your CSP. You have not changed your code - true, but your server has a CSP ruleset and according to that jQuery is refused. You will need to look into the response header of your main request as well as meta tags in your HTML to see what your CSP actually is. Then find where it was defined (either in server settings or meta tags or some custom code) and adjust it so jQuery will be allowed.

Alternatively you can download the jquery script locally and link it locally.

EDIT

I have read about this further, particularly at https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML

and this is particularly interesting, inspired from the link above:

const escapeHTMLPolicy = trustedTypes.createPolicy("myEscapePolicy", {
  createHTML: (string) => string.replace(/</g, "&lt;"),
});

let el = document.getElementById("myDiv");
const escaped = escapeHTMLPolicy.createHTML("<img src=x onerror=alert(1)>");
console.log(escaped instanceof TrustedHTML); // true
el.innerHTML = escaped;

Of course, having the HTML of

<div id="myDiv"></div>

I tested the above and it turned out to be nonfunctional in FireFox and functional in Chrome.

So you will need to see whether trustedTypes is supported at all:

if (typeof trustedTypes === "undefined") {
    alert("Trusted types are not supported");
} else {
    alert("Trusted types are supported");
}

Now, I would suggest that you could create a function that on the inside checks whether trustedTypes is supported at all and if so, then create a policy. Otherwise just create a function that has a method name. Then, you can call that function in any browser without worrying where it is supported and where not:

function getEscapeHTMLPolicy() {
    if (typeof trustedTypes === "undefined") {
        return {
            createHTML: (string) => string.replace(/</g, "&lt;"),
        }
    } else {
        return escapeHTMLPolicy = trustedTypes.createPolicy("myEscapePolicy", {
            createHTML: (string) => string.replace(/</g, "&lt;"),
        })
    }
}
let escPol = getEscapeHTMLPolicy();

window.addEventListener("load", function() {
    document.getElementById("mydiv").innerHTML = escPol.createHTML(`<p>foo</p>`);
});
<div id="mydiv"></div>
Lourdeslourie answered 28/11, 2023 at 13:46 Comment(5)
I tried to download jQuery locally and serve it directly, but exactly the same errors. About my CSP, I think it's ruled by Google within the Apps Script framework, or maybe I'm wrong, do you have any detailed information how to proceed?Rosetta
@WaximCorp please provide the full error, possibly as a screenshot in your question and please ping me here in the comment section when you added the info to your question.Lourdeslourie
done, screenshot added in the initial questionRosetta
edit: screenshot with correct file in network selectedRosetta
@WaximCorp thanks, looking into it!Lourdeslourie
K
-1

I was with a problem from policy in app script. In this case a used a upgrade in top to my html:

Error TrustedAdvisior CSP

Kylynn answered 8/1 at 12:29 Comment(2)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Carpo
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewEurasian

© 2022 - 2024 — McMap. All rights reserved.