Magento – How to create AJAX action for POST requests in Magento 2.3

ajaxcontrollersmagento2magento2.3routing

How to create a controller action that can be requested by POST properly in own custom payment module in Magento 2.3? How to create a parent class that will be extended by classes corresponding to controller actions which can be requested by POST properly in this version of Magento? I have created such a parent class:

<?php
namespace Billon\Payment\Controller;
/**
 * Ajax source
 */
class AjaxAction extends \Magento\Framework\App\Action\Action
{
    public function __construct(\Magento\Framework\App\Action\Context $context)
    {
        return parent::__construct($context);
    }
    public function execute()
    {
        //(...)
    }
}

The classes of the controller actions looks like this:

<?php
namespace Billon\Payment\Controller\Multishipping;
/**
 * Ajax source that initiate payment in multishipping checkout
 */
class Initiation extends \Billon\Payment\Controller\AjaxAction
{
    /**
     * Initiates the payment in multishipping checkout
     */
    public function execute()
    {
        parent::execute();
        //(...)
    }
}

Such actions can be request in Magento 2.0 – 2.2 by POST (above action by '(store address)/billon/multishipping/initiation'). However I can send only GET request properly to my controller actions in Magento 2.3. After I send POST request to my action, the action redirects to the referrer with HTTP code 302. I found a ugly solution in the parent class:

<?php
namespace Billon\Payment\Controller;
/**
 * Ajax source
 */
class AjaxAction extends \Magento\Framework\App\Action\Action
{
    public function __construct()
    {
        $this->execute();
        die();
    }
    public function execute()
    {
        //(...)
    }
}

This solution disables the translation with a function '__'. How to resolve this problem? How to disable the redirection of POST requests from the controller actions to the referrers in Magento 2.3 in proper way? How should I change my action classes to receive POST request? Could you help me?

Best Answer

To create AJAX action for POST requests in Magento 2.3, Please see the code below.

namespace Billon\Payment\Controller\Multishipping;

class Initiation extends \Magento\Framework\App\Action\Action
{

    protected $resultPageFactory;
    protected $jsonHelper;

    /**
     * Constructor
     *
     * @param \Magento\Framework\App\Action\Context  $context
     * @param \Magento\Framework\Json\Helper\Data $jsonHelper
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Magento\Framework\Json\Helper\Data $jsonHelper
    ) {
        $this->resultPageFactory = $resultPageFactory;
        $this->jsonHelper = $jsonHelper;
        parent::__construct($context);
    }

    /**
     * Execute view action
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        try {
            return $this->jsonResponse('your response');
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            return $this->jsonResponse($e->getMessage());
        } catch (\Exception $e) {
            $this->logger->critical($e);
            return $this->jsonResponse($e->getMessage());
        }
    }

    /**
     * Create json response
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function jsonResponse($response = '')
    {
        return $this->getResponse()->representJson(
            $this->jsonHelper->jsonEncode($response)
        );
    }
}