1

I checked this and built a Controller that executes an ajax request sent on adminhtml through a button, but I get an error 404 on my console.

POST http://myurl/system_config/customAjax/key/ade007809d7e313c38d42de6c2fa64ad8/?isAjax=true 404 (Forbidden)

I don't think you should pay much attention to the word "Forbidden" as this is an open issue on their repo and I guess it will be corrected. The important thing here is the error 404, and why doesn't it call my controller. Any ideas?

etc\adminhtml\system.xml:

<field id="vendor_actionbutton" type="button" sortOrder="26" showInDefault="1" showInWebsite="1" showInStore="0">
    <frontend_model>Vendor\Module\Block\Adminhtml\System\Config\Mybutton</frontend_model>
</field>

Block\Adminhtml\System\Config\Mybutton.php:

<?php
namespace Vendor\Module\Block\Adminhtml\System\Config;

use Magento\Backend\Block\Template\Context;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;

class Mybutton extends Field
{
    /**
     * @var string
     */
    protected $_template = 'Vendor_Module::system/config/customajax.phtml';

    /**
     * @param Context $context
     * @param array $data
     */
    public function __construct(
        Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    /**
     * Remove scope label
     *
     * @param  AbstractElement $element
     * @return string
     */
    public function render(AbstractElement $element)
    {
        $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
        return parent::render($element);
    }

    /**
     * Return element html
     *
     * @param  AbstractElement $element
     * @return string
     */
    protected function _getElementHtml(AbstractElement $element)
    {
        return $this->_toHtml();
    }

    /**
     * Return ajax url for send button
     *
     * @return string
     */
    public function getAjaxUrl()
    {
        return $this->getUrl('vendor_module/system_config/customAjax');
    }

    /**
     * Generate send button html
     *
     * @return string
     */
    public function getButtonHtml()
    {
        $button = $this->getLayout()->createBlock(
            'Magento\Backend\Block\Widget\Button'
        )->setData(
            [
                'id' => 'send_button',
                'label' => __('Send'),
            ]
        );

        return $button->toHtml();
    }
}

Controller\Adminhtml\System\Adminhtml\System\Config\CustomAjax.php:

<?php
namespace Vendor\Module\Controller\Adminhtml\System\Config;

class CustomAjax extends \Magento\Backend\App\Action
{
    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory
     */
    protected $resultJsonFactory;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory

    )
    {
        parent::__construct($context);
        $this->resultJsonFactory= $resultJsonFactory;
    }

    public function execute()
    {
        $params = $this->getRequest()->getParams();
        $resultJson = $this->resultJsonFactory->create();

        return $resultJson->setData([
            'messages' => 'Successfully. Params: ' . json_encode($params),
            'error' => false
        ]);
    }
}

view\adminhtml\templates\system\config\customajax.phtml:

<script>
    require([
        'jquery',
        'prototype'
    ], function(jQuery){

        var sendSpan = jQuery('#send_span');

        jQuery('#send_button').click(function () {
            var params = {};
            new Ajax.Request('<?php echo $block->getAjaxUrl() ?>', {
                parameters:     params,
                loaderArea:     false,
                asynchronous:   true
        });

    });
</script>

<?php echo $block->getButtonHtml() ?>
<span class="send-indicator" id="send_span">
    <img class="processing" hidden="hidden" alt="Sending" style="margin:0 5px" src="<?php echo $block->getViewFileUrl('images/process_spinner.gif') ?>"/>
    <img class="sent" hidden="hidden" alt="Sended" style="margin:-3px 5px" src="<?php echo $block->getViewFileUrl('images/rule_component_apply.gif') ?>"/>
    <span id="send_message_span"></span>
</span>

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="module" frontName="module">
            <module name="Vendor_Module" before="Magento_Backend" />
        </route>
    </router>
</config>

Is it maybe this vendor_module/system_config/customAjax wrong? Should I write it differently? (I have seen another module working with this expression though)

  • if you are on the page of your module you can use */*/customAjax – Mr. Lewis Sep 5 '17 at 18:08
  • if you need any advice could you please provide your app/code/Vendor/Module/etc/frontend/routes.xml ? – Mr. Lewis Sep 5 '17 at 18:10
  • @Mr.Lewis Do you mean that I should replace url vendor_module/system_config/customAjax with */*/customAjax? – Irini Koutaki Sep 6 '17 at 8:17
  • that is exactly what I mean – Mr. Lewis Sep 6 '17 at 11:42
0

I think you are missing your routes.xml file in app/code/Vendor/Module/etc/adminhtml/routes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="vendor_module" frontName="vendor_module">
            <module name="Vendor_Module" />
        </route>
    </router>
</config>
  • Now that I changed my routes.xml according to yours, I get an error 500, which I suppose is a good thing as it means that I have an error, but at least I manage to call the url, right? – Irini Koutaki Sep 6 '17 at 8:16
  • @IriniKoutaki yes check your controller code now you have error in your code – Murtuza Zabuawala Sep 6 '17 at 8:17
  • @IriniKoutaki Enable error display by uncomment #ini_set('display_errors', 1); in app/bootstrap.php then re-run ajax call and open your console and there the Network tab so you can see the actual 500 error. I recommend to enable preserve log in the Network tab in case the page will be redirected because of the 500 error. – Mr. Lewis Sep 6 '17 at 11:52
  • 1
    I just corrected the error that was causing the 500 error: I had $this->resultFactory= $resultJsonFactory; instead of $this->resultJsonFactory= $resultJsonFactory; – Irini Koutaki Sep 13 '17 at 14:47
  • and bottom of page you are using $this->resultJsonFactory – Murtuza Zabuawala Sep 13 '17 at 14:49
1

I experienced the same issue - receiving a 404 error on a custom ajax controller.

My ajax controller URL is retrieved using

$urlBuilder->getUrl('<frontname>/<action>');

and my controller file was at location

<module files>/Controller/Adminhtml/<Action.php>

After hours of debugging I found that the full path that Magento 2 creates for admin ajax requests is

<vendor>\<module>\controller\adminhtml\<action>\index

I then moved my controller file to be under:

<module files>/Controller/Adminthtml/<Action>/Index.php

The error was resolved - hope this helps someone else!

0

I don't know how it is possible, but i had the same error and i fixed it adding to controller

/**
 * Array of actions which can be processed without secret key validation
 *
 * @var string[]
 */
protected $_publicActions = ['test'];

and it starts to work, but now it continues to work even if $_publicActions is removed or commented out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.