I'm trying to implement an additional newsletter subscription option in the Shopware Storefront, where users can opt-in or opt-out of a secondary newsletter. I've created or modified the following files to handle this functionality:
- newsletter.html.twig: Extends the base newsletter template and adds a new checkbox form.
- handleAdditionalOptionSubmission() in controller: Handles the form submission via a POST request to the frontend.account.additionalOption route.
- index.js: Adds an event listener to the form and makes the AJAX request.
When I tick the checkbox and submit the form, I'm getting an AccessDeniedHttpException with the message "PageController can't be requested via XmlHttpRequest." Here's the relevant code:
newsletter.html.twig
{% sw_extends '@Storefront/storefront/page/account/newsletter.html.twig' %}
{% block page_account_overview_newsletter_content_form %}
{{ parent() }}
<form name="additionalOptionForm"
method="post"
action="{{ path('frontend.account.additionalOption') }}"
data-form-auto-submit="true"
data-form-auto-submit-options='{"useAjax": true, "ajaxContainerSelector": ".js-additional-option-wrapper"}'>
{# ... form content ... #}
</form>
{% endblock %}
function in controller
#[Route(path: '/account/newsletter/additional-option', name: 'frontend.account.additionalOption', methods: ['POST'], defaults: ['_loginRequired' => true, '_storefront' => true])]
public function handleAdditionalOptionSubmission(Request $request, RequestDataBag $dataBag, SalesChannelContext $context, CustomerEntity $customer): Response {
// ... controller logic ...
}
index.js
document.querySelectorAll('form[name="additionalOptionForm"]').forEach(form => {
form.addEventListener('submit', this.additionalOptionFormSubmit.bind(this));
});
additionalOptionFormSubmit(e) {
e.preventDefault();
var form = e.target;
var data = new FormData(form);
data.append('additionalOption', document.querySelector('#newsletterAdditionalOption').checked ? 'agreed' : 'not-asked');
data.append('csrf_token', document.querySelector('meta[name="csrf-token"]').getAttribute('content'));
this._client.post(form.getAttribute('action'), data, (response) => {
this.handleFormResponse(response);
});
return false;
}
Where am I going wrong, and how can I fix the AccessDeniedHttpException issue when submitting the form via AJAX?
I'm trying to implement an additional newsletter subscription option in the Shopware Storefront, where users can opt-in or opt-out of a secondary newsletter. I've created or modified the following files to handle this functionality:
- newsletter.html.twig: Extends the base newsletter template and adds a new checkbox form.
- handleAdditionalOptionSubmission() in controller: Handles the form submission via a POST request to the frontend.account.additionalOption route.
- index.js: Adds an event listener to the form and makes the AJAX request.
When I tick the checkbox and submit the form, I'm getting an AccessDeniedHttpException with the message "PageController can't be requested via XmlHttpRequest." Here's the relevant code:
newsletter.html.twig
{% sw_extends '@Storefront/storefront/page/account/newsletter.html.twig' %}
{% block page_account_overview_newsletter_content_form %}
{{ parent() }}
<form name="additionalOptionForm"
method="post"
action="{{ path('frontend.account.additionalOption') }}"
data-form-auto-submit="true"
data-form-auto-submit-options='{"useAjax": true, "ajaxContainerSelector": ".js-additional-option-wrapper"}'>
{# ... form content ... #}
</form>
{% endblock %}
function in controller
#[Route(path: '/account/newsletter/additional-option', name: 'frontend.account.additionalOption', methods: ['POST'], defaults: ['_loginRequired' => true, '_storefront' => true])]
public function handleAdditionalOptionSubmission(Request $request, RequestDataBag $dataBag, SalesChannelContext $context, CustomerEntity $customer): Response {
// ... controller logic ...
}
index.js
document.querySelectorAll('form[name="additionalOptionForm"]').forEach(form => {
form.addEventListener('submit', this.additionalOptionFormSubmit.bind(this));
});
additionalOptionFormSubmit(e) {
e.preventDefault();
var form = e.target;
var data = new FormData(form);
data.append('additionalOption', document.querySelector('#newsletterAdditionalOption').checked ? 'agreed' : 'not-asked');
data.append('csrf_token', document.querySelector('meta[name="csrf-token"]').getAttribute('content'));
this._client.post(form.getAttribute('action'), data, (response) => {
this.handleFormResponse(response);
});
return false;
}
Where am I going wrong, and how can I fix the AccessDeniedHttpException issue when submitting the form via AJAX?
Share Improve this question edited Nov 20, 2024 at 17:31 DarkBee 15.6k8 gold badges72 silver badges117 bronze badges asked Nov 20, 2024 at 15:36 AuhonaAuhona 2111 silver badge11 bronze badges1 Answer
Reset to default 1You're missing this part in your controller XmlHttpRequest' => true
#[Route(path: '/account/newsletter/additional-option', name: 'frontend.account.additionalOption', methods: ['POST'], defaults: ['_loginRequired' => true, XmlHttpRequest' => true, '_storefront' => true])]
public function handleAdditionalOptionSubmission(Request $request, RequestDataBag $dataBag, SalesChannelContext $context, CustomerEntity $customer): Response {
// ... controller logic ...
}