How do you safely encode a URL using JavaScript such that it can be put into a GET string?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
I assume that you need to encode the myUrl
variable on that second line?
转载于:https://stackoverflow.com/questions/332872/encode-url-in-javascript
Check out the built-in function encodeURIComponent(str)
and encodeURI(str)
.
In your case, this should work:
var myOtherUrl =
"http://example.com/index.html?url=" + encodeURIComponent(myUrl);
You have three options:
escape()
will not encode: @*/+
encodeURI()
will not encode: ~!@#$&*()=:/,;?+'
encodeURIComponent()
will not encode: ~!*()'
But in your case, if you want to pass a URL into a GET
parameter of other page, you should use escape
or encodeURIComponent
, but not encodeURI
.
See Stack Overflow question Best practice: escape, or encodeURI / encodeURIComponent for further discussion.
Stick with encodeURIComponent()
. The function encodeURI()
does not bother to encode many characters that have semantic importance in URLs (e.g. "#", "?", and "&"). escape()
is deprecated, and does not bother to encode "+" characters, which will be interpreted as encoded spaces on the server (and, as pointed out by others here, does not properly URL-encode non-ASCII characters).
There is a nice explanation of the difference between encodeURI()
and encodeURIComponent()
elsewhere. If you want to encode something so that it can safely be included as a component of a URI (e.g. as a query string parameter), you want to use encodeURIComponent()
.
Nothing worked for me. All I was seeing was the HTML of the login page, coming back to the client side with code 200. (302 at first but the same Ajax request loading login page inside another Ajax request, which was supposed to be a redirect rather than loading plain text of the login page).
In the login controller, I added this line:
Response.Headers["land"] = "login";
And in the global Ajax handler, I did this:
$(function () {
var $document = $(document);
$document.ajaxSuccess(function (e, response, request) {
var land = response.getResponseHeader('land');
var redrUrl = '/login?ReturnUrl=' + encodeURIComponent(window.location);
if(land) {
if (land.toString() === 'login') {
window.location = redrUrl;
}
}
});
});
Now I don't have any issue, and it works like a charm.
Personally, I find that many APIs want to replace " " with "+" so I use the following:
encodeURIComponent(value).replace(/%20/g,'+');
escape
is implemented differently in different browsers and encodeURI
doesn't encode most of the characters that are functional in a URI (like # and even /) -- it's made to be used on a full URI/URL without breaking it.
NOTE: You use encodeURIComponent for the values in the query string (not fields/value names and definitely not the entire URL). If you do it any other way it won't encode characters like =, ?, &, possibly leaving your query string exposed.
Example:
const escapedValue = encodeURIComponent(value).replace(/%20/g,'+');
const url = 'http://example.com/?myKey=' + escapedValue;
If you are using jQuery I would go for $.param
method. It URL encodes an object mapping fields to values, which is easier to read than calling an escape method on each value.
$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1
Similar kind of thing I tried with normal javascript
function fixedEncodeURIComponent(str){
return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}
Encode URL String
var url = $(location).attr('href'); //get current url
//OR
var url = 'folder/index.html?param=#23dd&noob=yes'; //or specify one
var encodedUrl = encodeURIComponent(url);
console.log(encodedUrl);
//outputs folder%2Findex.html%3Fparam%3D%2323dd%26noob%3Dyes
for more info go http://www.sitepoint.com/jquery-decode-url-string
encodeURIComponent() is the way to go.
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
BUT you should keep in mind that there are small differences from php version urlencode()
and as @CMS mentioned, it will not encode every char. Guys at http://phpjs.org/functions/urlencode/ made js equivalent to phpencode()
:
function urlencode(str) {
str = (str + '').toString();
// Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
// PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
return encodeURIComponent(str)
.replace(/!/g, '%21')
.replace(/'/g, '%27')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/\*/g, '%2A')
.replace(/%20/g, '+');
}
You can use esapi library and encode your url using the below function. The function endures that '/' are not lost to encoding while the remainder of the text contents are encoded:
function encodeUrl(url)
{
String arr[] = url.split("/");
String encodedUrl = "";
for(int i = 0; i<arr.length; i++)
{
encodedUrl = encodedUrl + ESAPI.encoder().encodeForHTML(ESAPI.encoder().encodeForURL(arr[i]));
if(i<arr.length-1) encodedUrl = encodedUrl + "/";
}
return url;
}
To prevent double encoding it's a good idea to decode the url before encoding (if you are dealing with user entered urls for example, which might be already encoded).
Lets say we have abc%20xyz 123
as input (one space is already encoded):
encodeURI("abc%20xyz 123") // wrong: "abc%2520xyz%20123"
encodeURI(decodeURI("abc%20xyz 123")) // correct: "abc%20xyz%20123"
To encode a URL, as has been said before, you have two functions:
encodeURI()
and
encodeURIComponent()
The reason both exist is that the first preserves the URL with the risk of leaving too many things unescaped, while the second encodes everything needed.
With the first, you could copy the newly escaped URL into address bar (for example) and it would work. However your unescaped '&'s would interfere with field delimiters, the '='s would interfere with field names and values, and the '+'s would look like spaces. But for simple data when you want to preserve the URL nature of what you are escaping, this works.
The second is everything you need to do to make sure nothing in your string interfers with a URL. It leaves various unimportant characters unescaped so that the URL remains as human readable as possible without interference. A URL encoded this way will no longer work as a URL without unescaping it.
So if you can take the time, you always want to use encodeURIComponent() -- before adding on name/value pairs encode both the name and the value using this function before adding it to the query string.
I'm having a tough time coming up with reasons to use the encodeURI() -- I'll leave that to the smarter people.
A URL should be encoded when there are special characters located inside the URL. For example:
console.log(encodeURIComponent('?notEncoded=&+'));
We can observe in this example that all characters except the string notEncoded
are encoded with % signs. URL encoding is also known as percentage encoding because it escapes all special characters with a %. Then after this % sign every special character has a unique code
Certain characters have a special value in a URL string. For example, the ? character denotes the beginning of a query string. In order to succesfully locate a resource on the web, it is necesarry to distinguish between when a character is meant as a part of string or part of the url structure.
JS offers a bunch of build in utility function which we can use to easily encode URL's. These are two convenient options:
encodeURIComponent()
: Takes a component of a URI as an argument and returns the encoded URI string.encodeURI()
: Takes a URI as an argument and returns the encoded URI string.Be aware of not passing in the whole URL (including scheme, e.g https://) into encodeURIComponent()
. This can actually transform it into a not functional URL. For example:
// for a whole URI don't use encodeURIComponent it will transform
// the / characters and the URL won't fucntion properly
console.log(encodeURIComponent("http://www.random.com/specials&char.html"));
// instead use encodeURI for whole URL's
console.log(encodeURI("http://www.random.com/specials&char.html"));
We can observe f we put the whole URL in encodeURIComponent
that the foward slashes (/) are also converted to special characters. This will cause the URL to not function properly anymore.
Therefore (as the name implies) use:
encodeURIComponent
on a certain part of a URL which you want to encode.encodeURI
on a whole URL which you want to encode.</div>