javascript XMLSerializer special characters in attribute - javascript

I`ve come across a problem when serializing special characters like TAB, linefeed and carriage return as an attribute value.
According to this http://www.w3.org/TR/1999/WD-xml-c14n-19991109.html#charescaping, these should be encoded as &\#x9;, &\#xA;, and &\#xD; respectively. But calling in chrome:
var root = new DOMParser().parseFromString('<root></root>', 'text/xml').documentElement;
root.setAttribute('a', 'first\nsecond');
var serialized = new XMLSerializer().serializeToString(root);
Gives a string < root a="first\nsecond"/> with the linefeed not escaped.
When loading that again:
var loaded = new DOMParser().parseFromString(serialized, 'text/xml').documentElement;
loaded.getAttribute('a');
returns "first second" and the linefeed was lost to just a space. Has anyone faced this issue before? Any help would be appreciated.
Thanks,
Viktor

I ran into this problem, and solved it by writing a function removeInvalidCharacters(xmlNode) that removes invalid characters (from nodeValues) in the XML tree. You can use it before serializing to ensure you don't get invalid characters.
You can find removeInvalidCharacters() in my stackoverflow question on the same topic
You can use removeInvalidCharacters() like this:
var stringWithSTX = "Bad" + String.fromCharCode(2) + "News";
var xmlNode = $("<myelem/>").attr("badattr", stringWithSTX);
var serializer = new XMLSerializer();
var invalidXML = serializer.serializeToString(xmlNode);
// Now cleanse it:
removeInvalidCharacters(xmlNode);
var validXML = serializer.serializeToString(xmlNode);
I've also filed an issue report against chrome, but its worth noting that IE9 has its own bugs in this department, so a fix w/o a workaround is probably a long time coming.

Related

Javascript replace in a string

I am familiar with the "replace" method in javascript is not enough. Possibly is it for my project is also a better way, then I would be glad if you also tells me this.
I would need the following:
I have a string with the following content:
var address = 'Beethovenstrasse 1, 97080 Würzburg';
This should be converted to:
var addressNew = '97080/W%C3%9CRZBURG/Beethovenstrasse/1';
And another string
var address = 'Hitzelsbergstr. 84, 83233 Bernau';
This should be converted to:
var addressNew = '83233%20Bernau,%20Hitzelsbergstr.%2084';
To explain why I need this: I need to convert the addresses are in the form of the string "address" in a database. The new string "addressNew" are then part of a link, which starts on mobile devices or TOMTOM navigation NAVIGON and the address to the destination passes by.
Ever Thanks for your help
A simple solution:
var address = 'Beethovenstrasse 1, 97080 Würzburg';
var parts = address.split(', ');
var newString = parts[1] + '/' + parts[0];
console.log(encodeURIComponent(newString));
This solution is very specific and does not handle other formats, but you should get some ideas.
You can split the string based on spaces and than you can adjeust the order and repalce characters with %20

Remove plus sign (+) in URL query string

I am trying get the string in the following URL to display on my webpage.
http://example.com?ks4day=Friday+September+13th
EDIT: The date in the URL will change from person to person as it's merged in by my CRM program.
I can get it to display on my webpage using the code below, the problem is the plus signs (+) come through as well.
eg. Friday+September+13th
What I need it to do is replace the plus signs (+) with spaces so it looks like this:
eg. Friday September 13th
I'm new to this so I'm having some trouble working it out.
Any help would be appreciated.
This is the code i'm using in a .js file
function qs(search_for) {
var query = window.location.search.substring(1);
var parms = query.split('&');
for (var i=0; i<parms.length; i++) {
var pos = parms[i].indexOf('=');
if (pos > 0 && search_for == parms[i].substring(0,pos)) {
return parms[i].substring(pos+1);;
}
}
return "";
}
This is the code i'm using on my webpage to make it display
<script type="text/javascript">document.write(qs("ks4day"));</script>
Although Bibhu's answer will work for this one case, you'll need to add decodeURIComponent if you have encoded characters in your URI string. You also want to make sure you do the replace before the decode in case you have a legitimate + in your URI string (as %2B).
I believe this is the best general way to do it:
var x = qs("ks4day"); // 'Friday+September+13th'
x = x.replace(/\+/g, '%20'); // 'Friday%20September%2013th'
x = decodeURIComponent(x); // 'Friday September 13th'
Here's an example of when it might be useful:
var x = '1+%2B+1+%3D+2';
x = x.replace(/\+/g, '%20'); // '1%20%2B%201%20%3D%202'
x = decodeURIComponent(x); // '1 + 1 = 2'
You can use replace() for this purpose
var dateString = 'Friday+September+13th';
var s = dateString .replace(/\+/g, ' ');
Parsing strings using regex is often prone to so many errors. Thankfully all modern browsers provide URLSearchParams to handle params from url strings in a proper way:
var params = new URLSearchParams(window.location.search);
var value = params.get('ks4day');
// "Friday September 13th"
Ps: There is also a good polyfill for old browsers.
Have you tried https://www.npmjs.com/package/querystring ?
import { parse } from 'querystring';
parse('ks4day=Friday+September+13th')
returns
{ 'ks4day': 'Friday September 13th' }
Assuming you are using something like Webpack that knows how to process import statements
If that's what you are doing, the plus sign will not be the only one that is going to give you a hard time. The apostrophe ('), equals (=), plus (+) and basically anything not in the permitted URL characters (see Percent-encoding # Wikipedia) is going to get escaped.
You are most likely looking for the decodeURIComponent function.

html entities in a javascript alert?

I have a string coming from a XML (which I can't edit) and I'd like to print it trough an alert in javascript.
Example of my string:
This is à string
And I need to print in an alert:
This is à string
is there a js html decode?
you could put the string in a dom element and read it out again, even without jquery:
https://stackoverflow.com/a/3700369/1986499
Edit by recent demand to include some code from another SO answer:
var div = document.createElement('div');
div.innerHTML = encoded;
var decoded = div.firstChild.nodeValue;
var encoded = "This is à string";
var decoded = $("<div/>").html(encoded).text();
alert(decoded);
I'm just a tiny bit late, but just in case anyone else finds this via Google (like I did), I thought I'd improve upon Imperative's answer.
function showbullet() {
var tempelement = document.createElement('div');
tempelement.innerHTML = "•";
alert("Here, have a bullet!\n" + tempelement.innerHTML);
}
showbullet();
I've tested this and confirmed it works in Chrome/43.0.2357.130 m; Firefox/32.0.1; Internet Explorer/9.0.8112.16421. There's no need to go mucking about with nodeValue's and what not; the entity will be replaced with it's associated character as soon as the assignment is complete. (Note, however, that doing alert(tempelement.innerHTML="•"); does not work in any of the browsers I tested!)

Firefox and IE won't call window.location.href if value is in a variable

I am trying to call a mailto: URI which is stored in a variable. When I do window.location.href = mailto_link; Firefox gives me the following error:
NS_ERROR_ILLEGAL_VALUE: Component returned failure code: 0x80070057
(NS_ERROR_ILLEGAL_VALUE) [nsIDOMLocation.href]
window.location.href = mailto_link;`
What IE says:
Object doesn't support this property or method
The code works in Chrome but not in IE nor Firefox.
my original function:
function email()
{
var nom = $('#nom').val();nom = encodeURIComponent(nom);
var compagnie = $('#compagnie').val();compagnie = encodeURIComponent(compagnie);
var rue = $('#rue').val();rue = encodeURIComponent(rue);
var ville = $('#ville').val();ville = encodeURIComponent(ville);
var province = $('#province').val();province = encodeURIComponent(province);
var cp = $('#cp').val();cp = encodeURIComponent(cp);
var remarques = $('#remarques').val();if(remarques ==""){remarques = "Aucune remarque.";}remarques = encodeURIComponent(remarques);
var quantite = $('#quantite').val();
var email= "someEmail#somedomain.com";
var subject= "Nouvelle commande";
var body_message= "%0D%0D%0D%0D"+nom+"%0D"+compagnie+"%0D"+rue+"%0D"+ville+", "+province+"%0D"+cp+"%0D%0D%0DRemarques:"+remarques+"%0D%0D Quantit%E9:"+quantite;
var mailto_link = 'mailto:'+email+'?subject='+subject+'&body='+body_message;
window.location.href = mailto_link;
}
UPDATE 1
I found out what was causing the issue for IE, although I am still looking to resolve it for Firefox. The problem for IE was that I had a console.log(); which wouldn't be recognized (IE8 and lower versions).
Here is a console.log() of the content of mailto_link:
mailto:someEmail#someDomain.com?subject=Nouvelle commande&body=Charger %0Dmodems des %CEseulement%0D%0D%0D%0Djshad%0Daskjda%0Daskdj%0Daskdj, askdj%0DJ9P%204A1%0D%0D%0DRemarques:asldk%0D%0D Quantit%E9:14
Firefox is apparently unable to handle the ISO 8859-1 characters above 128 in URLs. The problem disappears if you remove the %CE(Î) and %E9(é) from your logged example. Unfortunately, the only workaround I can think of requires manually replacing extended characters like those with an equivalent (perhaps HTMLEntities*). Since there is no native function to do so in Javascript, that could get quite annoying.
**Because HTMLEntities are only rendered properly in an HTML context, and mailto: URIs produce a plain-text message body, this is an imperfect solution. Below is a function that will do this, but the message will have instances of é and the like. Perhaps a more convenient solution is to convert accented characters to their equivalents in the first 128 ASCII characters as you mentioned in the comments.*
function encodeISO8859 (str) {
var rstr="";
for(var i=0; i<str.length; i++) {
var c = str.charCodeAt(i);
if(c>191&&c<=255&&!(c==215||c==247)){
console.log(c);
rstr += "&#"+c+";";
} else {
rstr += str.charAt(i);
}
}
return rstr;
}
This will turn any character in the ISO8859-1 character set (see bottom of page) into its equivalent HTMLEntity. Use this BEFORE encoding for URI:
var nom = $('#nom').val();nom = encodeURIComponent(encodeISO8859(nom));
Of course, only do this if the accented characters are absolutely necessary for comprehension, and there's likely to be overlap between many accents that use the same base character (like A).
I tried this and it worked for me, but I think the error code is probably related to one of the addons you may have Installed in firefox or IE, restarting the browser should help.
this is probably caused by an addon / userscript which is doing some
operations/modifications on the page while google redirects you do a
search result. you can try to run firefox in Troubleshoot Firefox
issues using Safe Mode and see if the error still occurs there. if not
disable all your addons & reenable them one in order to find out which
one is causing it exactly (you'll likely have to do a restart of the
browser after each one).
MORE

Search for a word and replace everything behind it

I hava a url like
mysite.net/home/index/page/XX
while XX is any number. I need to replace XX and remove everything that might be behind XX. So I would like to remove everything behind page/ by replacing it with a number.
There are a lot of methods for string manipulation http://www.w3schools.com/jsref/jsref_obj_string.asp
I know how to perform this but I am not sure which methods to use. So I ended with getting the lastIndexOf("page/"). So this +1 would give me the starting point for replacing the string. The entire length of the string would be the ending point.
Any ideas?
The following code will do the trick, by using regular expression:
"mysite.net/home/index/page/XX".replace(/\/page\/.*/, '/page/123')
var url = "mysite.net/home/index/page/XX"
return url.substr(-(url.length - (url.lastIndexOf("page/") + 5))))
I don't get your problem because you may have found everything you need...
var yourURI = "mysite.net/home/index/page/XX";
var theDelimiter = "page/";
var yourNewIndex = "42";
var yourNewURI = null;
var lastIndexOfDelimiter = yourURI.lastIndexOf(theDelimiter);
if (lastIndexOfDelimiter != -1)
{
yourNewURI = yourURI.substr(0, lastIndexOfDelimiter + theDelimiter.length) + yourNewIndex;
}
Is that what you want?
This isn't a direct answer to your question, but the way I solve this kind of problem is to have the server calculate a 'base url' (mysite.net/home/index/page/ in your case), and write it to a js variable at the time the page is built.
For two different ASP.NET MVC versions (there would be something similar you could do in any other framework) this looks like this:
var baseUrl = '#ViewBag.BaseUrl';
or
var baseUrl = '<%: ViewData["BaseUrl"] %>';
This has the big advantage that the page JS doesn't start to know about URL formation, so if you change your URL routing you don't find little breakages all over the place.
At least for ASP.NET MVC, you can use the frameworks routing API to generate the base URL at the server side.

Categories