<!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-form" src = "https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
<script async custom-element = "amp-list" src = "https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<script async custom-template = "amp-mustache" src = "https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
<script async custom-element = "amp-bind" src = "https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<style amp4email-boilerplate>
body {
visibility: hidden
}
</style>
</head>
<body>
<amp-state id = "selectedProduct">
<script type = "application/json">
{
"src": "imageSrc",
"title": "ProductName",
"price": "400"
}
</script>
</amp-state>
<div class = "container">
<amp-list width = "500" height = "500" layout = "responsive" src = "https://bounce.mailamp.in/similar-products" items = "products">
<template type = "amp-mustache">
<div class = "product-item" on = "tap:AMP.setState({
selectedProduct: {
src: {{src}},
title: {{title}},
price: {{price}}
}
})">
<amp-img class = "product-image" width = "100" height = "100" src = "{{src}}" alt = "Product Image"></amp-img>
<p>{{title}}</p>
<p>Price: ₹{{price}}</p>
<form method = "post" action-xhr = "https://bounce.mailamp.in/add-to-cart">
<input type = "hidden" name = "src" [value] = "selectedProduct.src">
<input type = "hidden" name = "title" [value] = "selectedProduct.title">
<input type = "hidden" name = "price" [value] = "selectedProduct.price">
<button type = "submit" class = "add-to-cart-button">Add to Cart</button>
</form>
</div>
</template>
</amp-list>
</div>
</body>
</html>
Я работаю над проектом AMP для электронной почты и пытаюсь реализовать интерактивный список продуктов, используя amp-list и amp-state. Однако у меня возникают проблемы с обновлением состояния при нажатии на продукт. Ниже приведен фрагмент кода, который я использую. Я был бы признателен за любые рекомендации о том, как правильно настроить это для динамического взаимодействия с пользователем.
В частности, я не уверен, правильно ли я использую AMP.setState для обновления состояния selectedProduct при нажатии на продукт. Любые идеи или исправления будут очень признательны!
Это еще одна проблема: я не могу сделать запрос с игровой площадки усилителя, хотя я добавил их конечные точки, но это работает, когда я делаю запрос из Gmail. Но проблема, с которой я столкнулся, заключается в том, что состояние не меняется при нажатии на div или кнопку. Если хотите, я могу отправить вам данные, которые получаю в списке amp-list.
Я попробовал образец, который вы предоставили в своем вопросе, и в Gmail. Я получил такую ошибку: Access to fetch at 'https://bounce.mailamp.in/similar-products' from source origin '[email protected]' has been blocked by AMP CORS policy: The 'AMP-Access-Control-Allow-Source-Origin' header has a value '[email protected]' that is not equal to the supplied source origin.
Значит, в Gmail она тоже не работает. Чтобы облегчить отладку, нам сначала понадобится работающая конечная точка XHR, которая отвечает на правильное состояние JSON.
Похоже, вы жестко запрограммировали значение заголовка AMP-Access-Control-Allow-Source-Origin
в [email protected]
в своей конечной точке. Было бы полезно, если бы вы могли изменить свой сервер, чтобы он вместо этого отвечал значением заголовка Amp-Access-Control-Allow-Source-Origin
в запросе, чтобы он работал для всех, кому нужна помощь в отладке с игровой площадки или Gmail (с источником [email protected]
).
res.setHeader('AMP-Access-Control-Allow-Source-Origin', [ '[email protected]', '[email protected]', 'Playground.amp.dev', ]); res.setHeader('Content-Type', 'application/json'); res.status(200).json(ответ); Я делаю это. Я добавил URL-адрес игровой площадки, но все еще не могу сделать запрос с игровой площадки. Знаете ли вы, как я могу добавить его для работы с игровой площадки. Извините, но я новичок в amp-email. Также спасибо за ответ
Я использую [ссылку] (playground.amp.dev/?runtime=amp4email) эту игровую площадку. Я также проверил это с помощью инкогнито и других пользователей, оно работает. Хотя я ничего не вижу на игровой площадке Googles, запрос xhr успешен. Я также добавляю скриншот к запросу. [ссылка] (imgur.com/gallery/vlMDj0u)
Извините, что засыпаю вас таким количеством вопросов, но можете ли вы сказать мне, как я могу показать список усилителей горизонтально? Я хочу отображать продукты в виде строк. Я попробовал добавить гибкий дисплей, но это не сработало.
Re: res.setHeader('AMP-Access-Control-Allow-Source-Origin', [ '[email protected]', '[email protected]', 'playground.amp.dev', ]);
— Я не думаю, что вы можете установить несколько значений для этого заголовка. Вы можете использовать подстановочный знак *
или отдельное значение, повторяющее значение параметра запроса __amp_source_origin
(AMP CORS V1). Я только что понял, что неправильно сказал «вместо этого ответить значением заголовка Amp-Access-Control-Allow-Source-Origin
в запросе» - я должен был сказать «вместо этого ответить значением параметра запроса __amp_source_origin
в запросе».
Причина, по которой ваш XHR работает на игровой площадке AMP (playground.amp.dev/?runtime=amp4email), заключается в том, что игровая площадка AMP не выполняет надлежащие проверки AMP CORS . Когда вы создаете свои электронные письма, вам все равно необходимо исправить проблемы AMP CORS, о которых я упоминал выше, иначе он не будет работать в Gmail. XHR по-прежнему не работает для меня на игровой площадке Gmail ( amp.gmail.dev), потому что игровая площадка Gmail выполняет проверки AMP CORS. По вашему другому вопросу о макете вам следует опубликовать новый вопрос.
В предоставленном вами образце есть несколько ортогональных проблем:
Вот как выглядит атрибут on
на <div>
после отрисовки шаблона Mustache:
tap:AMP.setState({
selectedProduct: {
src: https://bummer.in/cdn/shop/files/9000000664.2561_600x.jpg?v=1708346823,
title: Trunks - Disco82,
price: 599.00
}
})
Это приводит к ошибке, когда вы нажимаете на элемент div, чтобы запустить выполнение AMP вызова setState
:
Error: Parse error on line 3:
... src: https://bummer.in/cdn/sho
-----------------------^
Expecting '-', '+', '*', '/', '%', '&&', '||', '<=', '<', '>=', '>', '!=', '==', '?', '.', ',', '[', '}', got ':'
Вы должны увидеть эти ошибки в консоли JS.
Значения src
и title
необходимо заключить в кавычки, если значения являются строковыми литералами. См. примеры по адресу https://amp.dev/documentation/comComponents/email/amp-bind#deep-merge-with-amp.setstate().
setState
и отправкой формы нет зависимости от порядка.Когда вы нажимаете «Добавить в корзину», отправка формы не ожидает выполнения оценки amp-bind
скрытых элементов ввода формы после изменения состояния при нажатии внешнего div
. Они происходят параллельно в неопределенном порядке. В результате обычно происходит следующее: когда вы впервые нажимаете «Добавить в корзину», форма отправляется с полями ввода, установленными на значения по умолчанию для состояния AMP (src: imageSrc
и price: 400
), которые вы устанавливаете внутри тега <amp-state>
, как в отличие от значений, которые вы намереваетесь установить с помощью AMP.setState
.
Что вы можете сделать, так это гарантировать, что форма будет отправлена только после того, как произойдет setState
. Это можно сделать с помощью
submit
form.submit
для запуска отправки формы:Если вы присвоите элементу <form>
идентификатор DOM form
, вы можете сделать это:
<button on = "tap:AMP.setState({
selectedProduct: {
src: '{{src}}',
title: '{{title}}',
price: '{{price}}',
}
}), form.submit" type = "button" class = "add-to-cart-button">
Add to Cart
</button>
Вы можете отладить состояния AMP, выполнив AMP.printState()
в консоли JS в контексте фрейма AMP.
Даже после устранения вышеуказанных проблем отправка формы не работает, поскольку она не отвечает правильными заголовками CORS:
Access to fetch at 'https://bounce.mailamp.in/add-to-cart?__amp_source_origin=https%3A%2F%2Fplayground.amp.dev' from origin 'https://playground.amp.dev' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.
Огромное Вам спасибо, Вы очень помогли. Я внес изменения, которые вы мне сказали, и добавил credentials: true
, чтобы запрос xhr работал на игровой площадке, но когда я отправляю форму, в данных формы полезной нагрузки на вкладке запроса я вижу только источник и цену, я не вижу заголовок, но когда я ввожу какое-то другое свойство «имя», например ProductName, оно отображается в данных формы. Кроме того, список усилителей не отображается (amp.gmail.dev/playground), хотя запрос на получение успешен.
Атрибут name = "title"
в элементе ввода формы, вероятно, удаляется с помощью DOMPurify , который используется amp-mustache. DOMPurify пытается предотвратить разрушение DOM. В данном случае title
является запрещенным символом, поскольку это собственный атрибут какого-либо встроенного объекта JS, например document.title
. В этом случае атрибут name
не может затмить document
, но DOMPurify пытается быть консервативным и дезинфицировать, даже когда это не является строго необходимым.
Re: «Кроме того, список amp-list не отображается на (amp.gmail.dev/playground), хотя запрос на получение успешен» — см. мои заметки под вопросом stackoverflow.com/q/78357161/1397618. Вам нужно будет исправить проблемы AMP CORS, о которых я упоминал. GET XHR не работает на игровой площадке Gmail.
Большое спасибо за помощь. Я добавил это в бэкэнд const ampSourceOrigin = req.query.__amp_source_origin; res.set('AMP-Access-Control-Allow-Source-Origin', ampSourceOrigin);
и теперь это работает. Но когда я делаю сообщение формы xhr из (playground.amp.dev/?runtime=amp4email), я получаю неопределенное значение, но получаю журнал из (amp.gmail.dev/playground). Также я добавил новый вопрос о списке amp макет, если вы будете любезны взглянуть на него: (stackoverflow.com/questions/78370357/…)
Я еще раз попробовал образец на игровой площадке AMP (playground.amp.dev/?runtime=amp4email), и он у меня работает. Теперь это также работает на игровой площадке Gmail. Не уверен, где вы увидели «неопределенное».
Ой, извините за этот неясный комментарий, я получаю неопределенность на внутреннем сервере, когда делаю запрос на публикацию «добавить в корзину» из (Playground.amp.dev/?runtime=amp4email ), но когда я делаю тот же запрос из ( amp.gmail.dev/playground) я получаю журнал названия продукта, цены и источника.
На игровой площадке AMP используется multipart/form-data
, а на игровой площадке Gmail — application/x-www-form-urlencoded
. Убедитесь, что ваш сервер может обрабатывать оба варианта взаимозаменяемо.
Было бы полезно, если бы вы предоставили образец HTML с конечной точкой XHR, который поможет другим в отладке. Когда я вставляю предоставленный образец на игровую площадку, я получаю ошибку AMP CORS:
Request xhr failed: The amp-access-control-allow-source-origin must be equal to the amp source origin sent in the request.
.