Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #7196 (closed defect: untested)

Opened 2 years ago

Last modified 6 months ago

wrong URL generated by AjaxUpdater

Reported by: ollo Assigned to: mislav
Priority: normal Milestone:
Component: Prototype Version:
Severity: major Keywords:
Cc:

Description

I use prototype AjaxUpdater to expand items in a tree. As there is the need to submit the path (multiple parents) of the node to be opened and the parent node the URL looks like this:

http://admin.localhost/backend.view=menu&open=/sb2.localhost::sb/philosophie&subjectnode=/sb2.localhost::sb/philosophie

As you can see, i'm using mod_rewrite to expand 'backend.' to the real script with basic parameters, perhaps that's what puzzles prototype. The URL used by AjaxUpdater then looks like this, leading to a 'URL too long' fault of apache:

http://admin.localhost/backend.view=menu&open=/sb2.localhost::sb/philosophie&subjectnode=/sb2.localhost::sb/philosophie?getInterface=function%20getInterface()%20%7B%0A%20%20%20%20%5Bnative%20code%5D%0A%7D&addEventListener=function%20addEventListener()%20%7B%0A%20%20%20%20%5Bnative%20code%5D%0A%7D&location=http%3A%2F%2Fadmin.localhost%2Fbackend.view%3Dmenu&constructor=function%20()%20%7B%0A%20%20%20%20this.initialize.apply(this%2C%20arguments)%3B%0A%7D&onload=function%20onload(event)%20%7B%0A%20%20%20%20sbContextMenu.init()%3B%0A%7D&sbContextMenu=%5Bobject%20Object%5D&sbMenu=%5Bobject%20Object%5D&WindowUtilities=%5Bobject%20Object%5D&isIE=false&Dialog=%5Bobject%20Object%5D&Windows=%5Bobject%20Object%5D&navigator=%5Bobject%20Navigator%5D&ObjectRange=function%20()%20%7B%0A%20%20%20%20this.initialize.apply(this%2C%20arguments)%3B%0A%7D&window=%5Bobject%20Window%5D&Position=%5Bobject%20Object%5D&%24F=function%20(element)%20%7B%0A%20%20%20%20element%20%3D%20%24(element)%3B%0A%20%20%20%20var%20method%20%3D%20element.tagName.toLowerCase()%3B%0A%20%20%20%20return%20Form.Element.Serializers%5Bmethod%5D(element)%3B%0A%7D&Field=%5Bobject%20Object%5D&Form=%5Bobject%20Object%5D&%24%24=function%20%24%24()%20%7B%0A%20%20%20%20return%20Selector.findChildElements(document%2C%20%24A(arguments))%3B%0A%7D&Selector=function%20()%20%7B%0A%20%20%20%20this.initialize.apply(this%2C%20arguments)%3B%0A%7D&Insertion=%5Bobject%20Object%5D&Toggle=%5Bobject%20Object%5D&_nativeExtensions=true&%24=function%20%24(element)%20%7B%0A%20%20%20%20if%20(arguments.length%20%3E%201)%20%7B%0A%20%20%20%20%20%20%20%20for%20(var%20i%20%3D%200%2C%20elements%20%3D%20%5B%5D%2C%20length%20%3D%20arguments.length%3B%20i%20%3C%20length%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20elements.push(%24(arguments%5Bi%5D))%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20elements%3B%0A%20%20%20%20%7D%0A%20%20%20%20if%20(typeof%20element%20%3D%3D%20%22string%22)%20%7B%0A%20%20%20%20%20%20%20%20element%20%3D%20document.getElementById(element)%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20Element.extend(element)%3B%0A%7D&Ajax=%5Bobject%20Object%5D&%24R=function%20(start%2C%20end%2C%20exclusive)%20%7B%0A%20%20%20%20return%20new%20ObjectRange(start%2C%20end%2C%20exclusive)%3B%0A%7D&%24H=function%20%24H(object)%20%7B%0A%20%20%20%20if%20(object%20%26%26%20object.constructor%20%3D%3D%20Hash)%20%7B%0A%20%20%20%20%20%20%20%20return%20object%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20new%20Hash(object)%3B%0A%7D&Hash=function%20(obj)%20%7B%0A%20%20%20%20Object.extend(this%2C%20obj%20%7C%7C%20%7B%7D)%3B%0A%7D&%24w=function%20%24w(string)%20%7B%0A%20%20%20%20string%20%3D%20string.strip()%3B%0A%20%20%20%20return%20string%20%3F%20string.split(%2F%5Cs%2B%2F)%20%3A%20%5B%5D%3B%0A%7D&%24A=function%20(iterable)%20%7B%0A%20%20%20%20if%20(!iterable)%20%7B%0A%20%20%20%20%20%20%20%20return%20%5B%5D%3B%0A%20%20%20%20%7D%0A%20%20%20%20if%20(iterable.toArray)%20%7B%0A%20%20%20%20%20%20%20%20return%20iterable.toArray()%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20var%20results%20%3D%20%5B%5D%3B%0A%20%20%20%20%20%20%20%20for%20(var%20i%20%3D%200%2C%20length%20%3D%20iterable.length%3B%20i%20%3C%20length%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20results.push(iterable%5Bi%5D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A..... ONLY HALF OF THE URL, REST WAS CUT DUE TO ERROR IN TRAC!!! (maximum recursion limit reached)

The error occurs after i switched from Prototype 1.5.0_rc1 to 1.5.0, the code generating the url in my script is the same, and it's submitted correctly to the AjaxUpdater constructor (verified by alert just before the call). However, the strange thing is that the first call (after reloading the page, e.g.) works and expands the tree, and the second (and every after that) one is corrupted.

Change History

01/19/07 12:16:13 changed by ollo

Small addition to avoid confusion:

I noticed that i actually send the same node path twice, a remain from old code, where i had used the node IDs instead of their path. I cut it down to URLs like:

http://admin.localhost/backend.view=menu&open=/sb2.localhost::sb/philosophie

The problem still remains, though.

01/19/07 16:55:40 changed by eventualbuddha

Can you please provide a bit more information? For example, what browser(s) does this happen in? What is your code that is generating the URL? What are you passing into Ajax.Request?

01/19/07 19:02:24 changed by ollo

Sorry, could have thought of that in the first place... Tested it in several Browsers now:

Firefox 2.0.0.1: inserts the apache error page instead of the HTML expected (Request-URI Too Large - The requested URL's length exceeds the capacity limit for this server). That was the Browser this occured to me and on which my original post was based.

Opera 9.02: does remove the HTML it was supposed to replace (the node in the Tree disappears) plus some surrounding HTML it's in (e.g. the expand-'+' is gone afterwards although it's not in the updated container)

IE6: Nothing does happen, it just switches the expand icon's state without further changes.

I'd expect the different behaviour depends on how the browsers handle long URLs themselves resp. broken HTML (the Apache error page is a whole page in itself, so duplicate <html>-tags and the like are obviously not ok). In all 3 browsers the RC1 code works perfectly. Sidenote: i know some of the ids used are not valid, because they start with ':', but that should not be a problem, at least it hasn't been before with RC1, and the problem occurs on request, not response.

Function generating the URLs:

var sbMenu = {
	
	// open/close menu branches
	toggleMenuEntry : function (sNodeID) {
	
		var nodeIcon = $('icon' + sNodeID);
		
		if (nodeIcon.getAttribute('name') == 'close') {
			sbMenu._updateMenuEntry(sNodeID, 'close');
		} else {
			sbMenu._updateMenuEntry(sNodeID, 'open');
		}
		
	},
	
	// just reload a branch
	reloadMenuEntry : function (sNodeID) {
		sbMenu._updateMenuEntry(sNodeID, 'open');
	},
	
	// update a branch with desired method
	_updateMenuEntry : function (sNodeID, sMode) {
	
		var nodeItem = $('entry' + sNodeID);
		var nodeIcon = $('icon' + sNodeID);
		var nodeChildren = $('children' + sNodeID);
		
		var sNodePath = sNodeID;
		
		sNodePath = sNodePath.replace(/::/g, '!');
		sNodePath = sNodePath.replace(/:/g, '/');
		sNodePath = sNodePath.replace(/!/g, '::');
		
		switch (sMode) {
		
			case 'reload':
				alert('reload not finished yet');
				/*var sUrl = 'backend.view=menu&subjectnode=' + sNodePath;
				var sID = 'entry' + sNodeID;
				var myAjaxOpener = new Ajax.Updater( 
					sID,
					sUrl, 
					{
						method: 'get', 
						parameters: null 
					}
				);*/
				break;
				
			case 'close':
				nodeIcon.setAttribute('name', 'open');
				nodeIcon.setAttribute('src', 'modules/sb_system/themes/_admin/images_sysicons/tree_open.gif');
				
				if (nodeChildren != null) {
					nodeItem.removeChild(nodeChildren);
				}
				
				var sUrl = 'backend.view=menu&close=' + sNodePath //+ '&subjectnode=' + sNodePath;
				var myAjaxCloser = new Ajax.Request(
					sUrl, 
					{
						method: 'get', 
						parameters: null
					}
				);
				break;
				
			case 'open':
				nodeIcon.setAttribute('name', 'close');
				nodeIcon.setAttribute('src', 'modules/sb_system/themes/_admin/images_sysicons/tree_close.gif');
				
				var sUrl = 'backend.view=menu&open=' + sNodePath //+ '&subjectnode=' + sNodePath;
				//alert(sUrl);
				var sID = 'entry' + sNodeID;
				var myAjaxOpener = new Ajax.Updater( 
					sID,
					sUrl, 
					{
						method: 'get', 
						parameters: null 
					}
				);
				break;
		
		}
	
	}

}

HTML of the tree all collapsed (sorry, not prettyprinted, i'll manually beautify one entry):

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" href="modules/sb_system/themes/_admin/stylesheets_css/styles_tree.css" type="text/css" media="all"><script type="text/javascript" src="modules/sb_system/themes/_admin/scripts_js/prototype/prototype.js"></script><script type="text/javascript" src="modules/sb_system/themes/_admin/scripts_js/window/window.js"></script><script type="text/javascript" src="modules/sb_system/themes/_admin/scripts_js/menu.js"></script></head><body onload="sbContextMenu.init();"><div id="contextmenu"></div><div class="tree"><ul class="tree"><li><a href="backend.view=welcome" class="type core" target="main">solidMatter</a><ul id="children">
<li id="entry:sb2.localhost::sb">
  <a href="javascript:sbMenu.toggleMenuEntry(':sb2.localhost::sb')">
    <img id="icon:sb2.localhost::sb" src="modules/sb_system/themes/_admin/images_sysicons/tree_open.gif" name="open">
  </a>
  <a target="main" id=":sb2.localhost::sb" class="type site" href="backend.nodeid=ec3f5a676d7c43e1a7a539cb483ca394">
    solidbytes
  </a>
  </li>
<li id="entry:sb2.localhost::mmm"><a href="javascript:sbMenu.toggleMenuEntry(':sb2.localhost::mmm')"><img id="icon:sb2.localhost::mmm" src="modules/sb_system/themes/_admin/images_sysicons/tree_open.gif" name="open"></a><a target="main" id=":sb2.localhost::mmm" class="type multimediamanager" href="backend.nodeid=307f66febf2e460b81d1613a4d9350a5">Multimediamanager</a></li><li id="entry:sb2.localhost::templates"><img src="modules/sb_system/themes/_admin/images_sysicons/blank.gif" alt=""><a target="main" id=":sb2.localhost::templates" class="type templatemanager" href="backend.nodeid=f23806d022824fe5ae510ff5ffffeb3c">Templates</a></li><li id="entry:solidMatter::imageprocessing"><a href="javascript:sbMenu.toggleMenuEntry(':solidMatter::imageprocessing')"><img id="icon:solidMatter::imageprocessing" src="modules/sb_system/themes/_admin/images_sysicons/tree_open.gif" name="open"></a><a target="main" id=":solidMatter::imageprocessing" class="type imageprocessing" href="backend.nodeid=f81ddc601c723510a74e7c97f42353a6">Bildbearbeitung</a></li><li id="entry:solidMatter::preferences"><a href="javascript:sbMenu.toggleMenuEntry(':solidMatter::preferences')"><img id="icon:solidMatter::preferences" src="modules/sb_system/themes/_admin/images_sysicons/tree_open.gif" name="open"></a><a target="main" id=":solidMatter::preferences" class="type preferences" href="backend.nodeid=0080dc1373b84eb0b2096988254ef361">Systemsteuerung</a></li><li id="entry:papierkorb"><img src="modules/sb_system/themes/_admin/images_sysicons/blank.gif" alt=""><a target="main" id=":papierkorb" class="type trashcan" href="backend.nodeid=f81ddc601c604510a74e7c97f42353a6">Papierkorb</a></li></ul></li></ul></div></body></html>

(follow-up: ↓ 5 ) 02/07/07 01:03:25 changed by mislav

  • owner changed from sam to mislav.
  • status changed from new to assigned.
  • summary changed from [Prototype 1.5] wrong URL generated by AjaxUpdater to wrong URL generated by AjaxUpdater.

Thanks for the report. That indeed is an insanely long URL :(

You should have made the example minimal, this much JS and HTML is no good since I have to recreate your whole app environment to reproduce this... Oh well. I'll report back as soon as I come up with something

(in reply to: ↑ 4 ) 02/07/07 13:57:07 changed by ollo

Replying to mislav:

I posted it because it was requested and wanted to provide the exact environment, but perhaps it's not necessary. I haven't tried, but would assume that it also happens when just passing the URL mentioned in my initial post to the Ajax.Updater in the way i did. It's a weird bug already, but it would be even weirder when there were any other side-effects involved. But hey, i've only scratched the surface of what's weird about JS until now, though.

01/30/08 04:03:08 changed by Tobie

  • status changed from assigned to closed.
  • resolution set to untested.

Please kinldy provide a reduced failing test case. Thank you.