skip to Main Content

I am trying to access a URL via AJAX in Magento 2’s admin area. I have tried many things but every time the response is 404 Forbidden.

Firefox’s console shows this:
Firefox Console: Headers
Firefox Console: Params

This is the code my module has:

Vendor/Module/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Module" setup_version="1.0.0">
    </module>
</config>

Vendor/Module/etc/adminhtml/routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="adminhtml">
            <module name="Vendor_Module" before="Magento_Backend" />
        </route>
    </router>
</config>

AJAX JS Code using Prototype:

new Ajax.Request('<?php /* @escapeNotVerified */ echo $block->getAdminUrl(); ?>adminhtml/action/add', {
    method: 'post',
    parameters: {'order_id' : <?php /* @escapeNotVerified */ echo $block->getOrderId(); ?>},
    onSuccess: function(response) {
        console.log($response);
        this.add();
    }.bind(this)
});

Vendor/Module/Controller/Adminhtml/Action/Add.php

<?php
namespace VendorModuleControllerAdminhtmlAction;

class Add extends MagentoBackendAppAction
{
    protected $_context;
    protected $_pageFactory;
    protected $_jsonEncoder;

    public function __construct(
        MagentoBackendAppActionContext $context,
        MagentoFrameworkJsonEncoderInterface $encoder,
        MagentoFrameworkViewResultPageFactory $pageFactory
    ) {
        $this->_context = $context;
        $this->_pageFactory = $pageFactory;
        $this->_jsonEncoder = $encoder;
        parent::__construct($context);
    }

    public function execute()
    {
        $response = array('status' => 'success');
        $this->getResponse()->representJson($this->_jsonEncoder->encode($response));
        return;
    }
}

Please tell me how I can access this admin URL via AJAX.

3

Answers


  1. <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
        <router id="admin">
            <route id="adminhtml" frontName="xyz">
                <module name="Vendor_Module" before="Magento_Backend" />
            </route>
        </router>
    </config>
    

    I am convinced that missing frontName in the route configuration file is the reason why error 404 is popping up so replace xyz with your frontName as specified above

    Login or Signup to reply.
  2. I had tried all of the above methods but non of them are working or incomplete so I had decided to answer it in details:
    Following will be module minimal diagram

    enter image description here

    1)

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
        <router id="admin">
            <route frontName="groupproduct" id="groupproduct">
                <module before="Magento_Backend" name="Textmimedia_Partpicker"/>
            </route>
        </router>
    </config>
    

    2)

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Levosoft_Partpicker" setup_version="1.0.0"/>
    </config>
    

    3) Need to declare admin router

        <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
        <router id="admin">
            <route frontName="groupproduct" id="groupproduct">
                <module before="Magento_Backend" name="Levosoft_Partpicker"/>
            </route>
        </router>
    </config>
    

    4)

    <?php
    
    
    namespace LevosoftPartpickerControllerAdminhtmlImagetag;
    
    /**
     * Class Save
     *
     * @package LevosoftPartpickerControllerAdminhtmlImagetag
     */
    class Save extends MagentoBackendAppAction
    {
    
        protected $resultPageFactory;
        protected $jsonHelper;
    
        /**
         * Constructor
         *
         * @param MagentoBackendAppActionContext  $context
         * @param MagentoFrameworkJsonHelperData $jsonHelper
         */
        public function __construct(
            MagentoBackendAppActionContext $context,
            MagentoFrameworkViewResultPageFactory $resultPageFactory,
            MagentoFrameworkJsonHelperData $jsonHelper,
            PsrLogLoggerInterface $logger
        ) {
            $this->resultPageFactory = $resultPageFactory;
            $this->jsonHelper = $jsonHelper;
            $this->logger = $logger;
            parent::__construct($context);
        }
    
        /**
         * Execute view action
         *
         * @return MagentoFrameworkControllerResultInterface
         */
        public function execute()
        {
            try {
                return $this->jsonResponse('your response');
            } catch (MagentoFrameworkExceptionLocalizedException $e) {
                return $this->jsonResponse($e->getMessage());
            } catch (Exception $e) {
                $this->logger->critical($e);
                return $this->jsonResponse($e->getMessage());
            }
        }
    
        /**
         * Create json response
         *
         * @return MagentoFrameworkControllerResultInterface
         */
        public function jsonResponse($response = '')
        {
            return $this->getResponse()->representJson(
                $this->jsonHelper->jsonEncode($response)
            );
        }
    }
    

    Now Client Part which is actually bit tricky I am calling it in js file like somefilename.js

    var ajaxRequest;
                    var saveUrl = gpImageTagSaveUrl+'?isAjax=true'; //module url declared globally in module;
    
                    ajaxRequest = $.ajax({
                        showLoader: true,
                        url: saveUrl,
                        data: {form_key: window.FORM_KEY},
                        type: 'POST',
                        dataType: 'json',
                        beforeSend: function () {
                            $('#loader').show();
                        }
                    });
                    //Show successfully for submit message
                    ajaxRequest.done(function (response, textStatus, jqXHR) {
                        $("#ajaxResponse").html(response);
                        $('#loader').hide();
                    });
    
                    //On failure of request this function will be called
                    ajaxRequest.fail(function () {
                        //show error
                        $("#ajaxResponse").html('Oops, An error occured, please' +
                            ' try again later!');
                        $('#loader').hide();
                    });
    

    gpImageTagSaveUrl is globel variable which will hold your modules url you can declare it in some js file like following

    enter image description here

    I had used catalog_product_edit.xml file because I want it at product edit location you can add it in your required file or in default.xml if required on all.

    <?xml version="1.0"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column"
          xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            <referenceContainer name="js">
                <block class="MagentoBackendBlockTemplate" template="Textmimedia_Partpicker::js.phtml"
                       name="custom_js_backend"/>
            </referenceContainer>
        </body>
    </page>
    

    Now in js.phtml declare action url like following:

    <script>
        require([
            "prototype"
        ], function () {
            window.gpImageTagSaveUrl = '<?= /** @noEscape */ $block->getUrl('groupproduct/imagetag/save')?>';
        });
    </script>
    
    Login or Signup to reply.
  3. You should have to provide admin user somehow. I think will be better to create API endpoint instead.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search