Inline javascript is getting stripped off from the AJAX response by Prototype JS Ajax.Request method

六月ゝ 毕业季﹏ 提交于 2019-12-24 16:09:04

问题


I am working on a Magento store trying to code a widget's javascript layer with the help of Prototype js framework.

In my grid.js file AJAX call is setup like that:

loadTabContent: function(tab, tabType){

        if(tab === undefined || tabType === undefined){
            return this;
        }

        entityId = tab.id.split('-')[3];

        request = new Ajax.Request(
            this.tabContentLoadUrl,
            {
                method:'get', 
                onSuccess: this.onTabContentLoad.bind(tab),
                onFailure: this.ajaxFailure.bind(this),
                evalJS: true,
                parameters: {
                    id: entityId, 
                    type: tabType
                }
            }
        );
    }

Below is the success handler:

onTabContentLoad: function(transport){

        if(transport && typeof transport.responseText !== undefined){
            try{
                response = transport.responseText;
            }catch (e) {
                console.log('PARSE ERROR', e);
                response = {};
            }

            entityId = this.id.split('-')[3];
            tabType = this.id.split('-')[1];

            if(response && $('tab-' + tabType + '-' + entityId + '-contents')){
                $('tab-' + tabType + '-' + entityId + '-contents').update(response);    
            }
        }
    },

The content for the div is getting updated correctly by the AJAX call but there is some inline JS in response which is not working. I can't even see that javascript snippet in Elements tab(chrome developer tool)

Below is the code that handles the AJAX request on server side:

public function renderTabContentAction()
    {
        $entityId = Mage::app()->getRequest()->getParam('id');
        if( ! $entityId){

            $this->getResponse()->setHeader('HTTP/1.0', '400', true);
            $this->getResponse()->setBody('Invalid parameters provided.');
        }

        $tabType = Mage::app()->getRequest()->getParam('type');
        if( ! $tabType){

            $this->getResponse()->setHeader('HTTP/1.0', '400', true);
            $this->getResponse()->setBody('Invalid parameters provided.');
        }

        Mage::register('current_entity_id', $entityId);
        Mage::register('current_tab_type', $tabType);

        $tabHtml = $this->_getTabsHtml($entityId, $tabType);    


        $this->getResponse()->setHeader('HTTP/1.0', '200', true);
        $this->getResponse()->setBody($tabHtml);
    }

Below is the response that gets passed to onTabContentLoad AJAX handler:

 <div class="vertical-tabs">
      <div class="tabs">
        <div class="tab" id="tab-vertical-137-2441">
          <input type="radio" id="label-vertical-product-tab-137-2441" name="product-tab-group-137">
          <label class="tabs-label" for="label-vertical-product-tab-137-2441">PG-10ml</label>
          <div class="content" id="tab-vertical-137-2441-contents">
          </div>
        </div>
        <div class="tab" id="tab-vertical-137-2442">
          <input type="radio" id="label-vertical-product-tab-137-2442" name="product-tab-group-137">
          <label class="tabs-label" for="label-vertical-product-tab-137-2442">PG-15ml</label>
          <div class="content" id="tab-vertical-137-2442-contents">
          </div>
        </div>

      </div>
    </div>
   <script type="text/javascript">
     bulkOrderGrid.initVerticalTabs();
     bulkOrderGrid.activateTab('2441', 'VERTICAL');
   </script>

You can see that the SCRIPT tags are there in the response. Its just when the content gets updated using Element.update function it strips off the SCRIPT tags. That's what I can understand so far.

NOTE: I have also used Ajax.Updater along with evalScripts:true and Ajax.Request along with evalJS:true.

Got stuck here. Any help would be much appreciated.

UPDATES:

Since I am using Element.update function to refresh the section. The source of the problem is this part of the code in prototype.js around line no. 2048. I can see its getting executed in js debugger. It does evaluates the js code but also removes the SCRIPT tags from the source. Commenting out stripScripts works fine.

   else {
     element.innerHTML = content.stripScripts();
   }

   content.evalScripts.bind(content).defer();

回答1:


I think your problem is that the Ajax response is passed through String#evalScripts() but the context is not the global context so instead of your script block do this

<script type="text/javascript">
 window.bulkOrderGrid.initVerticalTabs();
 window.bulkOrderGrid.activateTab('2441', 'VERTICAL');
</script>

if that doesnt fix it - than you can directly run transport.responseText.evalScripts() but you still need the window. in your script block to resolve the scope of the variables.




回答2:


You are correct Element.update() remove script tag. you should use Element.innerHTML



来源:https://stackoverflow.com/questions/36922262/inline-javascript-is-getting-stripped-off-from-the-ajax-response-by-prototype-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!