Backbone keeps decoding my query string params. For example when I do
var query_string = encodeURIComponent('New York')
Backbone.history.navigate('search?location='+query_string, {trigger: true})
I get an URL with path:
/#search?location=New York
instead of
/#search?location=New%20York
I'm not using pushState and I've read that in 1.0.0 version he decodes the fragment in the URL. So any suggestions how can I achieve this, or something similar maybe?
Unicode characters in location.pathname are percent encoded so they're
decoded for comparison.
https://github.com/jashkenas/backbone/blob/master/backbone.js#L1587
You might have to fork the library and remove or modify decodeFragment method.
Related
I have the following route in my AngularJS application
var accountactivation = {
name: 'accountactivation',
url: '/activate/:code',
templateUrl: 'views/account/activation.html',
controller: 'AccountActivationController',
authenticate: false
};
Added like this to the router
$stateProvider.state(accountactivation)
This is a account activation system, where :code is the activation code. This code is URL encoded.
The problem : sometime :code contains % character. Then the navigator is redirected to login instead of displaying the account activation page.
Example of routes
http://localhost:9000/#!/activate/c43q6zb2 works correctly
http://localhost:9000/#!/activate/c43q6zb2% is redirected to login (sometimes lead to a blank page)
http://localhost:9000/#!/activate/c43q6zb2Fxb%2FxQkjc2qnjc39QEYTQtpVmgWbw2gzNII0z8QRFrRhz%2FNC4LxzqBIYw5tqM9NaY8ejTxIRXQCfTh8hFszyARL%2Ff9MoOp2MvzNulqefVczsuGpZA8RZArQk doesn't work either
Is it possible to allow angularjs routes to have parameters containing prcentages signs ?
How I encode my activation key : For info, I'm using java URLEncoder with UTF-8 encoding charset
Thank you for your help :)
https://en.wikipedia.org/wiki/Percent-encoding
Because the percent character ( % ) serves as the indicator for percent-encoded octets, it must be percent-encoded as %25 for that octet to be used as data within a URI.
So it seems your URI is invalid with just a %. You need to encode it properly. Either use %25 so it will decode as %, or remove it...
I'm having some trouble getting my angular application to parse my json-data correctly.
When my json-feed contains e.g. { "title": "Halldórsson Pourié" }
my application shows Halld�rsson Pouri�
I figure the problem is the charset, but i can't find where to change it.
Currently i am using ng-bind-html and using $sce.trustAsHtml(), and I'm very sure the problem occurs when $http.get(url) parses my json.
So how do i tell $http.get(url) to parse the data with a specific charset?
I had a similar issue and resolved it by using:
encodeURIComponent(JSON.stringify(p_Query))
where p_Query is a JSON containing the details of the request (i.e. your { "title": "Halldórsson Pourié" }).
EDIT:
You may also need to add to the header of your GET request the following:
'Content-Type': 'application/x-www-form-urlencoded ; charset=UTF-8'
Had same problem with accented characters and some scientific notation in text/JSON fields and found that AngularJS (or whatever native JavaScript XHR/fetch functions it is using) was flattening everything to UTF-8 no matter what else we tried.
The other respondent here claimed that UTF-8 should somehow still be accommodating your extended character set, but we found otherwise: taking samples of the source data directly, we loaded it into text editor with different encodings and UTF-8 would still squash extended characters to that � placeholder.
In our case, the encoding was ISO-8859-15 but you may be sufficient with ISO-8859-1.
Try adding this $http configuration to your $http.get() call, accordingly:
$http.get(url, {
responseType: 'arraybuffer',
transformResponse: function(data) {
let textDecoder = new TextDecoder('ISO-8859-15'); // your encoding may vary!
return JSON.parse(textDecoder.decode(data));
}
});
This should intercept AngularJS default response transformation and instead apply the function here. You will, of course, want to consider adding some error handling, etc.
If there are better ways to do this without a custom transformResponse function, I have yet to find anything in the AngularJS documentation.
$http.get(url, {responseType: 'arraybuffer', }).then(function (response) { var textDecoder = new TextDecoder('ISO-8859-1'); console.log(textDecoder.decode(response.data));});
This code will replace all your � placeholders into normal characters.
I'm trying to use dot (.) in query string parameter but its not working.
This URL is working fine:
http://localhost:9000/search-result?majTFMin=0&majTFMax=100&majDOMCFMin=0&majDOMCFMax=100&majRefDomainsMin=0&majRefDomainsMax=100&majRefIPsMin=0&majRefIPsMax=100&majRefDomainsEDUMin=0&majRefDomainsEDUMax=100&majRefDomainsGOVMin=0&majRefDomainsGOVMax=100&selectedTLDs=com
But not this one as it contains a dot in a parameter:
http://localhost:9000/search-result?majTFMin=0&majTFMax=100&majDOMCFMin=0&majDOMCFMax=100&majRefDomainsMin=0&majRefDomainsMax=100&majRefIPsMin=0&majRefIPsMax=100&majRefDomainsEDUMin=0&majRefDomainsEDUMax=100&majRefDomainsGOVMin=0&majRefDomainsGOVMax=100&selectedTLDs=co.uk
When I'm trying to open above URL (with dot), it just prints:
Cannot GET /search-result?majTFMin=0&majTFMax=100&majDOMCFMin=0&majDOMCFMax=100&majRefDomainsMin=0&majRefDomainsMax=100&majRefIPsMin=0&majRefIPsMax=100&majRefDomainsEDUMin=0&majRefDomainsEDUMax=100&majRefDomainsGOVMin=0&majRefDomainsGOVMax=100&selectedTLDs=co.uk
And nothing else, not even any HTML tags(has checked that in view source)
I have read lots of posts which says that . can be used in query string without encoding, but I don't understand why its not working here. I think it has some issue with AngularJS.
I'm using ui-router for state change and passed value to controller.
Any help would be appreciated.
If you are using connect-history-api-fallback on your server (like lite-server does), the URLs with a dot are not rewritten by default.
connect-history-api-fallback code
if (parsedUrl.pathname.indexOf('.') !== -1) {
logger(
'Not rewriting',
req.method,
req.url,
'because the path includes a dot (.) character.'
);
return next();
}
Starting with connect-history-api-fallback version 1.2.0 the URLs with dots are allowed and you can solve this problem by using a a rewrite roule
Example
If your URL with dot is /search-result and you angular app lives in the index.html page you can add a rewrite rule to the connect-history-api-fallback like this
rewrites: [
{
from: /^\/search-result/,
to: 'index.html'
}
}
]
I am using graph API of Facebook and I call it through camel framework. My query has non ASCII characters (e.g. küçük). I am getting the following exception:-
Cause:
org.apache.commons.httpclient.URIException: Invalid query
at org.apache.commons.httpclient.URI.parseUriReference(URI.java:2049)
at org.apache.commons.httpclient.URI.<init>(URI.java:147)
at org.apache.commons.httpclient.HttpMethodBase.getURI
at org.apache.commons.httpclient.HttpClient.executeMethod
at org.apache.commons.httpclient.HttpClient.executeMethod
at org.apache.camel.component.http.HttpProducer.executeMethod
at org.apache.camel.component.http.HttpProducer.process
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:122)
Does camel support non ASCII characters in URI? If not, what other things can be done?
example URL: https://graph.facebook.com/?ids=http://www.example.com/küçük
"URL encoding replaces non ASCII characters with a "%" followed by hexadecimal digits." (more info here)
You could try this:
URL url = new URL(uri.toASCIIString());
or maybe
String xstr = URLEncoder.encode("维", "utf-8");
So this is what we were able to do to fix the issue.
In Apache Camel, the HTTP_URI component does not accept any special characters, even after encoding them. This is a bug in Camel which is not yet closed.
Fortunately for us, the special characters would only appear in the Query String of the URL and not the main URI part. Camel provides another component HTTP_QUERY, which can successfully parse and understand encoded UTF-8 characters. By setting it in the Header, we were able to get rid of the issue.
So basically first we encode the URL to UTF-8 and then set the HTTP_QUERY value as query string. This worked like charm.
e.g. (Scala)
.setHeader(Exchange.HTTP_QUERY, _.in[HttpRequest].uri.split(?).head)
.setHeader(Exchange.HTTP_URI, _.in[HttpRequest].uri)
Use encodeURIComponent(url) it will work
We need an encoded semi-colon character in our url parameter but angular does not encode this character.
The resource we use looks something like this:
app.factory('TestResource', ['$resource', function ($resource) {
return $resource('http://somedomain.com');
}]);
app.run(['TestResource', function (TestResource) {
TestResource.query({
q: 'sin;sout'
});
}]);
This is the result we get:
http://somedomain.com/?q=sin;sout
We want the url to be:
http://somedomain.com/?q=sin%3Bsout
But if we pre-encode the parameter before sending the % char get's encoded like this:
http://somedomain.com/?q=sin%253Bsout
How can we get the desired result? (http://somedomain.com/?q=sin%3Bsout)
Angular uses its own function to encode the URL. And that function doesn't encode characters that usually don't need to be encoded like / or ?. ; is such a character, too. It's used in matrix URIs, e.g. So Angular's behavior actually conforms to the standard, but it could be a problem when such characters are used literally, i.e. without a special meaning. That seems to be the case here.
Since the URL is build just before sending the request, there's not much we can do. There is kind of a loophole though: Only parameters are encoded, not the base URL. So any workaround would involve creating the URL or at least a part of it yourself.
You could add an interceptor, that adds the properly encoded parameters to the URL before Angular does it. You could even completely replace Angular's behavior that way.
UPDATE:
Another solution came to my mind. The $http service delegates sending the actual request to the $httpBackend service which receives the already constructed URL. Using a decorator you can replace either the ; or the incorrectly encoded %253B with %3B right before the request is sent:
app.config(function($provide) {
$provide.decorator('$httpBackend', function($delegate) {
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
url = url.replace(';', '%3B');
$delegate(method, url, post, callback, headers, timeout, withCredentials, responseType);
};
})
});
Building on zeroflagL's answer one could consider changing the replace to change all occurrences of the semi-colon (as it is written it will only replace the first semi-colon):
url = url.replace(/;/g, '%3B');
There is a closed issue for this https://github.com/angular/angular.js/issues/9224
path: Don't escape semicolons. Breaks matrix parameters, and no evidence that Angular's current behavior is problematic.
query: Escaping the entire query string would be unwise, as it breaks an established (albeit archaic) expectation for servers to be able to handle semicolon-delimited query strings.
query values: Probably safe to escape, especially if the server interprets semicolons as query delimiters. Passing complex data types (ie. JSON) via query parameters is a bad idea, but "real-world" string values often contain semicolons, and it seems like a good idea to escape them.
I'll go with zeroflagL's answer but only changing the query values. Like this:
$provide.decorator('$httpBackend', function($delegate) {
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
var a = document.createElement('a');
a.href = url;
if(a.search.length > 1) {
var params = a.search.substring(1).split('&');
for (var i=0; i<params.length; i++) {
var param = params[i].split('=');
if(param[1]) {
params[i] = [param[0], param[1].replace(';', '%3B')].join('=');
}
}
url = url.substring(0, url.lastIndexOf('?')) + '?' + params.join('&');
}
$delegate(method, url, post, callback, headers, timeout, withCredentials, responseType);
};
});
You can use encodeURIComponent() method:
q: encodeURIComponent('sin;sout')