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?
2
4 Answers
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>
0
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>
1
-
1
"As per the Google Issue Tracker" – please edit your answer to link the issue you are referring to.
– Bergi6 hours ago
Raised on the issue tracker already. Hopefully, will be something that is fixed on Google’s side soon
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, "<"),
});
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, "<"),
}
} else {
return escapeHTMLPolicy = trustedTypes.createPolicy("myEscapePolicy", {
createHTML: (string) => string.replace(/</g, "<"),
})
}
}
let escPol = getEscapeHTMLPolicy();
window.addEventListener("load", function() {
document.getElementById("mydiv").innerHTML = escPol.createHTML(`<p>foo</p>`);
});
<div id="mydiv"></div>
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?
– Waxim Corp18 hours ago
-
@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.
– Lajos Arpad18 hours ago
-
done, screenshot added in the initial question
– Waxim Corp18 hours ago
-
edit: screenshot with correct file in network selected
– Waxim Corp18 hours ago
-
@WaximCorp thanks, looking into it!
– Lajos Arpad16 hours ago
web.dev/articles/trusted-types
18 hours ago
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.
8 hours ago