PDA

View Full Version : URL encode space to %20, not %2b



markalroberts
22 Sep 2009, 1:48 AM
Ext.urlEncode converts spaces into +'s for the querystring part of the Url. This also gets used for a store proxy (method=GET)

I'd like the default to be %20 instead... (i.e. so that store.baseParams { search: 'Joe Bloggs' } becomes url?search=Joe%20Bloggs

Any ideas?

httpdotcom
22 Sep 2009, 3:41 AM
Override the method.

Animal
22 Sep 2009, 3:45 AM
But it already does doesn't it?

http://i131.photobucket.com/albums/p286/TimeTrialAnimal/asperusual.jpg

markalroberts
22 Sep 2009, 5:12 AM
Ah, yes, you're correct :) it was further down the line:



contactSearchForm.getForm().getValues();


Returns


Object field=FullName action=Starts filter=mark+robertsaction
"Starts"field
"FullName"filter
"mark+roberts"

So, it's something in the Form that's doing this.

Animal
22 Sep 2009, 5:24 AM
Use the POST method

markalroberts
22 Sep 2009, 5:27 AM
Thanks... And this does indeed work... however, I want to use GET though... :)

Animal
22 Sep 2009, 5:43 AM
URLs use "+" for space.

Animal
22 Sep 2009, 5:44 AM
Sounds like you are double encoding. Show code.

markalroberts
22 Sep 2009, 6:28 AM
Well, the querystring portion of a URLs _can_ use + for space but it can also use %20.

i.e. i want to my GET proxy to construct a url "http://server/contact/find?search=mark%20roberts", not "http://server/contact/find?search=mark+roberts"

The call to getValues() of my form is returning values with "+" as a space substitute, which I use to setBaseParam() against the store, and that's the way i get it on the server... so, here I then need to convert "+" back to " ", which seems an unnecessary overhead.

I can try to knock up a working sample of this problem...

Animal
22 Sep 2009, 6:33 AM
Again, I can't see that:

http://i131.photobucket.com/albums/p286/TimeTrialAnimal/again_it_works.jpg

Animal
22 Sep 2009, 6:35 AM
So again, show code.

markalroberts
23 Sep 2009, 1:38 AM
Apologies for delay - hectic day yesterday.

This explains what I'm after, I think:



Ext.onReady(function() {
new Ext.FormPanel({
id: 'searchForm',
xtype: 'form',
renderTo: document.body,
items: [
{
xtype: 'textfield',
name: 'searchFilter',
value: 'Joe Bloggs',
fieldLabel: 'Search'
}, {
xtype: 'button',
text: 'Search',
handler: function() {
var extValue = this.findParentByType('form').getForm().getValues().searchFilter;
// Joe+Bloggs
var jqueryValue = $('#searchForm :input').val();
// Joe Bloggs
}
}
]
});
});


Basically, I want Ext to return my form values without replacing spaces with '+'

Thank.

Animal
23 Sep 2009, 1:45 AM
What's this dollary stuff?

Ext does not do what you are saying. There is no code anywhere in it to put "+" signs in.

You are not showing the code which does submission.

markalroberts
23 Sep 2009, 1:48 AM
Dollary stuff is jquery - pretty good stuff it is too.

comment out this line if you're not using jquery, and you should still see that getValues() on the form returns the value with '+'s instead of spaces... or does it not for you?

Animal
23 Sep 2009, 2:03 AM
Of course not. Ext has no nonsense in it which plays with "+" signs.

You have a problem elsewhere in your code. In code that you are not showing. So we can't help.

http://i131.photobucket.com/albums/p286/TimeTrialAnimal/working_of_course.jpg

markalroberts
23 Sep 2009, 2:14 AM
Ok, I have isolated the problem.

It's related to the Ext jQuery adapter. If I include this:



<script language="javascript" type="text/javascript" src="Scripts/jquery/jquery-1.3.2.js"></script>
<script language="javascript" type="text/javascript" src="Scripts/ext/ext-jquery-adapter.js"></script>


Ext returns form values with + instead of space. If I remove jQuery, and just use the ext-base instead:



<script language="javascript" type="text/javascript" src="Scripts/ext/ext-base.js"></script>


The same code then returns the expected value.

Animal
23 Sep 2009, 2:21 AM
The lesson is: Ditch jQuery

Animal
23 Sep 2009, 2:23 AM
It is jQuery's serialize function which does it.

Animal
23 Sep 2009, 2:27 AM
Yep, it contains this nonsense:



// Return the resulting serialization
return s.join("&").replace(/%20/g, "+");

markalroberts
23 Sep 2009, 3:08 AM
Well, there's no way we're ditching jQuery - it's an excellent and well-tested framework.

I was given to understand that Ext supports jQuery, but clearly this is a bug in Ext's support.

Not sure where to go from here, perhaps I should raise this as a bug with the Ext dev team?

Condor
23 Sep 2009, 3:48 AM
You are using the jQuery adapter, so Ext will use jQuery for all base library stuff, like url encoding.

So, if jQuery encodes the url with + signs and you don't want that, then you should blame jQuery and not Ext.

As an alternative, you could replace the ext-jquery-adapter with ext-base. Then Ext will use it's own base library, which does correct url encodes, but you will still be able to use the jQuery library itself.

The only drawback of this solution is that the file is a bit larger (= slower to load).

ps. The ext-base library can do most stuff that jQuery can, e.g.

var extValue = Ext.select('#searchForm :input')[0].getValue();

Animal
23 Sep 2009, 4:01 AM
That code in in jQuery.

jQuery decides to change spaces to plus signs.

If you use jQuery as a foundation, then you have to put up with jQuery's bugs.

There's really no point in sticking to jQuery. You gain nothing from it except a few extra K pageweight.

markalroberts
23 Sep 2009, 4:04 AM
Thanks.

So, ex-base.js is 32kb and ext-jquery-adapter.js is 19kb, so if the hit of replacing one with the other is an additional 13kb in my initial download, then I can handle that.

Not entirely sure, but I think Ext uses jQuery for ajax requests too... guess I'll just have to learn the hard way if I need/don't need to use ext's jQuery adapter at a later stage.

Don't suppose there's any documentation anywhere as to exactly what jQuery functionality is used by the adapter?

Animal
23 Sep 2009, 4:11 AM
Don't forget to add jquery onto that which you no longer need.

As I said, the only thing you gain from using jQuery as a foundation is extra pageweight.

Condor
23 Sep 2009, 4:11 AM
It's not only the fact that the file is bigger. It also causes separate registries to be kept for elements (e.g. listeners), which could make your application slower (depends on application - difference could be minimal).

Using an adapter, all internal Element, Fx and Ajax handling is done using the other library.

markalroberts
23 Sep 2009, 4:12 AM
There are a lot of very good reaons to use jQuery. It's a brilliantly elegant api for providing the kind of web 2.0 features we're giving our customers, it has a vibrant community with plugins for just about everything, and it's incredibly robust.

I don't really want to turn this thread into a jQuery vs Ext rant - that would just be futile. I like them both for different reasons. The thing I like about being a web application developer is that I don't have to choose "one way"... I could go back to being a windows developer if that was that case :)

Thanks,
Mark.

jan.cinert
2 Feb 2016, 2:14 PM
I analyzed the problem.
I introspected source code of ExtJS 3 and jQuery 2.

jQuery in `serialize` function before version 3.0.0-beta1 encodes space as plus.
That is not incorrect, it is in line with specification.

There are two specifications on how to encode space in form values.
1. as + (https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1)
2. as %20 (http://tools.ietf.org/html/rfc3986#section-2.1)

There are following problems in ExtJS 3 source code.

1. Ext.form.BasicForm.getValues(asString)
if value of asString parameter is false then form values are first url encoded and then url decoded.
That itself is not a bug, but an architecture of the code is not good.
There should not be encoding and decoding in that case.

getValues : function(asString){
var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
if(asString === true){
return fs;
}
return Ext.urlDecode(fs);
}



2. jQuery adapter, different url encoding strategies for space

Ext.lib.Ajax.serializeForm is using jQuery `serialize` function and that uses the strategy 1 (see above).
Ext.urlDecode contains same source code as core adapter. Both are using strategy 2.

serializeForm : function(form){
return jQuery(form.dom||form).serialize();
}



urlDecode : function(string, overwrite){
if(Ext.isEmpty(string)){
return {};
}
var obj = {},
pairs = string.split('&'),
d = decodeURIComponent,
name,
value;
Ext.each(pairs, function(pair) {
pair = pair.split('=');
name = d(pair[0]);
value = d(pair[1]);
obj[name] = overwrite || !obj[name] ? value :
[].concat(obj[name]).concat(value);
});
return obj;
}



Proposed fix:

Change source code of Ext.urlDecode of jQuery adapter to be able of decoding url encoding of strategy 1.

urlDecode : function(string, overwrite){
if(Ext.isEmpty(string)){
return {};
}
var obj = {},
pairs = string.replace(/\+/g, '%20').split('&'),
d = decodeURIComponent,
name,
value;
Ext.each(pairs, function(pair) {
pair = pair.split('=');
name = d(pair[0]);
value = d(pair[1]);
obj[name] = overwrite || !obj[name] ? value :
[].concat(obj[name]).concat(value);
});
return obj;
}



Note: Int ExtJS 4 the problem 1 was resolved. The source code of Ext.form.BasicForm.getValues function was heavily refactored (removing unnecessary pair of encoding and decoding)