AMP邮件中内联JS脚本(amp-script)无法正常工作求助
AMP邮件中amp-script文本翻译功能无法运行问题排查
我尝试在AMP邮件的<body>标签中添加amp-script标签,包裹动态内容并调用内联JS脚本实现文本翻译功能,但该功能无法正常运行。以下是我的实现代码,恳请帮忙排查解决:
<!doctype html> <html ⚡4email data-css-strict> <head> <meta charset="utf-8"> <script async src="https://cdn.ampproject.org/v0.js"></script> <script async custom-element="amp-script" src="https://cdn.ampproject.org/v0/amp-script-0.1.js"></script> <script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script> <script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script> <script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script> <style amp4email-boilerplate>body{visibility:hidden}</style> <style amp-custom> h1 { margin: 1rem; } button{ margin:1rem; } amp-script{ color:black; } </style> <meta name="amp-script-src" content="sha384-qhLQva9Z_2XXttcLseJyLWCi1nCwqWuO6pgC-RrXg3wEgakMc_sjfbcA4VdTovMU "> </head> <body> <amp-script layout="container" script="inline_amp" class="amp-script-sample"> <button id="hello2">Translate Hindi!</button> <h1 class="local" >Join To Reverie With Website Localization</h1> <amp-carousel id="carousel-with-preview" width="800" height="400" layout="responsive" type="slides" on="slideChange:AMP.setState({currentCat: event.index})"> <amp-img layout="fill" src="https://amp.dev/static/img/docs/tutorials/firstemail/photo_by_caleb_woods.jpg" alt="photo courtesy of Unsplash"></amp-img> <amp-img layout="fill" src="https://amp.dev/static/img/docs/tutorials/firstemail/photo_by_craig_mclaclan.jpg" alt="photo courtesy of Unsplash"></amp-img> <amp-img layout="fill" src="https://amp.dev/static/img/docs/tutorials/firstemail/photo_by_lightscape.jpg" alt="photo courtesy of Unsplash"></amp-img> <amp-img layout="fill" src="https://amp.dev/static/img/docs/tutorials/firstemail/photo_by_nick_karvounis.jpg" alt="photo courtesy of Unsplash"></amp-img> </amp-carousel> </amp-script> <script id="inline_amp" type="text/javascript" target="amp-script"> let button = document.querySelector('#hello2'); button.addEventListener('click', () => { let element = document.body.getElementsByClassName('local'); console.log(element); for (let child of element) { console.log(child.innerHTML); var raw = JSON.stringify({ "data": [child.textContent], "isBulk": false, "ignoreTaggedEntities": false }); var requestOptions = { method: 'POST', headers: { "Content-Type": "application/json", "REV-API-KEY": "a241d264e7caae4b2e55d269d27c236e8", "REV-APP-ID": "rev.platform", "src_lang": "en", "tgt_lang": "hi", "REV-APPNAME": "transliteration", "domain": "1", "cnt_lang": "en" }, body: raw, redirect: 'follow' }; fetch("https://revapi.reverieinc.com/", requestOptions) .then(response => response.json()) .then(result => { debugger child.innerHTML= result.responseList[0].outString[0]; debugger console.log(result.responses) }) .catch(error => console.log('error', error)); } }); </script> </body> </html>
问题排查与解决方案
1. amp-script内禁止嵌套AMP自定义元素
amp-script容器内不能直接嵌套其他AMP自定义元素(如amp-carousel),这违反AMP安全规则,会导致脚本执行异常。需将amp-carousel移到amp-script标签外部。
2. DOM选择器作用域错误
amp-script运行在沙箱环境中,document.body.getElementsByClassName('local')无法跨作用域选择元素,应直接在脚本作用域内查找:
let elements = document.getElementsByClassName('local');
3. SHA校验值不匹配
<meta name="amp-script-src">中的SHA384值必须与内联脚本内容完全一致。若修改过脚本,需重新生成正确的SHA384哈希值替换现有内容。
4. DOM操作限制
amp-script沙箱中,直接修改innerHTML可能受限,建议改用textContent更新文本:
child.textContent = result.responseList[0].outString[0];
5. CORS请求限制
AMP邮件对fetch请求有严格CORS要求,需确保目标API返回允许邮件客户端访问的CORS响应头。
修正后的示例代码
<!doctype html> <html ⚡4email data-css-strict> <head> <meta charset="utf-8"> <script async src="https://cdn.ampproject.org/v0.js"></script> <script async custom-element="amp-script" src="https://cdn.ampproject.org/v0/amp-script-0.1.js"></script> <script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script> <script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script> <script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script> <style amp4email-boilerplate>body{visibility:hidden}</style> <style amp-custom> h1 { margin: 1rem; } button{ margin:1rem; } amp-script{ color:black; } </style> <!-- 请重新生成正确的SHA384值替换此处 --> <meta name="amp-script-src" content="sha384-你的新SHA384哈希值"> </head> <body> <amp-script layout="container" script="inline_amp" class="amp-script-sample"> <button id="hello2">Translate Hindi!</button> <h1 class="local" >Join To Reverie With Website Localization</h1> </amp-script> <amp-carousel id="carousel-with-preview" width="800" height="400" layout="responsive" type="slides" on="slideChange:AMP.setState({currentCat: event.index})"> <amp-img layout="fill" src="https://amp.dev/static/img/docs/tutorials/firstemail/photo_by_caleb_woods.jpg" alt="photo courtesy of Unsplash"></amp-img> <amp-img layout="fill" src="https://amp.dev/static/img/docs/tutorials/firstemail/photo_by_craig_mclaclan.jpg" alt="photo courtesy of Unsplash"></amp-img> <amp-img layout="fill" src="https://amp.dev/static/img/docs/tutorials/firstemail/photo_by_lightscape.jpg" alt="photo courtesy of Unsplash"></amp-img> <amp-img layout="fill" src="https://amp.dev/static/img/docs/tutorials/firstemail/photo_by_nick_karvounis.jpg" alt="photo courtesy of Unsplash"></amp-img> </amp-carousel> <script id="inline_amp" type="text/javascript" target="amp-script"> let button = document.querySelector('#hello2'); button.addEventListener('click', () => { let elements = document.getElementsByClassName('local'); for (let child of elements) { var raw = JSON.stringify({ "data": [child.textContent], "isBulk": false, "ignoreTaggedEntities": false }); var requestOptions = { method: 'POST', headers: { "Content-Type": "application/json", "REV-API-KEY": "a241d264e7caae4b2e55d269d27c236e8", "REV-APP-ID": "rev.platform", "src_lang": "en", "tgt_lang": "hi", "REV-APPNAME": "transliteration", "domain": "1", "cnt_lang": "en" }, body: raw, redirect: 'follow' }; fetch("https://revapi.reverieinc.com/", requestOptions) .then(response => response.json()) .then(result => { child.textContent = result.responseList[0].outString[0]; console.log(result) }) .catch(error => console.log('error', error)); } }); </script> </body> </html>
内容的提问来源于stack exchange,提问作者Abhilash Pandey
相关产品推荐
相关产品推荐

