开发者

Escape Quotes In HTML5 Data Attribute Using Javascript

I'm using jQuery's .data() to work with custom HTML5 data attributes where the value of the attribute needs to be able to contain both single quotes and double quotes:

<p class="example" data-example="She said "WTF" on last night's show.">

I know using character codes like &quot; in the data attribute value could make the above work, but I can't always control how the values are inputted. Plus, I need to be able to use HTML tags in the markup, like this:

<p class="example" data-example="
She said "<abbr title="What The F***">WTF</abbr>" on last night's show.
">

If some form of .replace() is the answer, then it needs to be done before the value is read by .data()—maybe by applying it across the entire <body>?

Normal backslash escaping like <abbr title="te\'st">WTF</abbr> doesn't work either.

Ideally this wo开发者_JAVA百科uld have the flexibility to work w/ both:

data-example="..." and data-example='...'

But if it's only possible one way then I could at least roll with that. Ideas?

Update - some more context:

I'm working on this for responsejs.com. An actual application of this might be to only load a sidebar for browsers above a certain width (and have this handled in the browser rather than PHP). In the case of WordPress for example, the sidebar could contain widgets, images, etc. The quotes within PHP tags are a non-issue b/c they are parsed into HTML before they get to the browser. Example:

<aside id="primary" class="sidebar" 

        data-oweb=' 

            <?php dynamic_sidebar( 'primary' ); ?>

        '
    >

    optional default markup for mobile and no-js browsers here

</aside>


There is no way around it, you have to escape the values properly, or the HTML can't be parsed properly. You can't use Javascript to correct the code after it is parsed, because then it has already failed.

Your example with proper HTML encoding would be:

<p class="example" data-example="She said &quot;&lt;abbr title=&quot;What The F***&quot;&gt;WTF&lt;/abbr&gt;&quot; on last night's show.">

You can't use backslash to escape characters, because it's not Javascript code. You use HTML entities to escape characters in HTML code.

If you can't control how the data is input, then you are screwed. You simply have to find a way to take control over it.


Use encodeURI to escape quotation marks in your JSON object. Parse the string with decodeURI.

var popup = document.getElementById('popup'),
    msgObj = JSON.parse(decodeURI(popup.dataset.message));

console.log(msgObj);
<a id="popup" href="#" data-message="%7B%22title%22:%22Print%22,%22message%22:%22Printing%20not%20yet%20implemented%22%7D" />


As I use the data attribute to transport some data together with the html element from PHP to the JavaScript, I just use base64_encode on the backend , then on the client side use base64Decode(input) to get the data back. This way I avoid any and all escaping orgy. The JavasScript code I use is located here http://www.webtoolkit.info/


If they have to be HTML strings with " and ' and whatnot, why not just make separate HTML elements for them: http://jsfiddle.net/N7XXu/.

E.g. the HTML:

<p class="example" data-which="1">a</p>

<p class="example-data" data-which="1">She said "<abbr title="What The F***">WTF</abbr>" on last night's show.</p>

in combination with the following JavaScript:

$('.example').each(function() {
    var correspondingElem = $('.example-data[data-which="'
                              + $(this).data('which')
                              + '"]');
    $(this).data('example', correspondingElem.html());
});

alert($('.example').data('example'));

Of course, hide the .example-data elements.


For it to be proper html, you have to escape the troublesome characters. I'd escape them with HTML entities. This means that whatever tool is being used to input this information would have have to store them properly and/or the tool retrieving them on the back end would have to escape them.

Then if you want to use them in your JS, you'd have to run some find-and-replace functions to convert the characters back into HTML and quotes.

Most back-end dev languages have some sort of 'htmlescape/unescape' functionality, so that shouldn't be to hard.

To unescape it via jQuery, here's something found via a quick Google: http://www.naveen.com.au/javascript/jquery/encode-or-decode-html-entities-with-jquery/289


Here is a simple tool I created you can use to encode html:

The trick is to escape it twice.

I added an additional \n replace to preserve multiline text since it gets discarded by text().

In addition you need to escape the quotes to make it safe for a data attribute.

<div id="esc"></div>
<textarea id="escinput" placeholder="Enter text"></textarea>
<script>
    $("#escinput").bind("change paste keyup", function(){
        $("#esc").text($(this).val().replace(/\n/g,'\\n'));
        $("#esc").text($("#esc").html().replace(/"/g, '&quot;'));
    });            
</script>

This should create a data attribute safe string.

You can test it here: http://jsfiddle.net/SplicePHP/n6HFq/

To decode it back to html simply use:

<script>
    var attr = $("#idOfElement").data('attribute');
    var decoded = $('<textarea/>').html(attr).val();
</script>


have you tried using single quotes for your data?

Like this:

<p class="example" data-example='She said "WTF" on last night's show.'>


As this answer suggestest , here is a possible solution :

var popup = $('#placeholder');
popup.html(`
<div data-message="${encodeURI("i could be what ever you need \' \" i will escape ! ")}" >
</div>
`);

console.log(decodeURI(popup.find('div').data("message")));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="placeholder">
</div>

The key here is that :

wierdText = decodeURI(someText))

and :

someText = encodeURI(wierdText)

are reverse functions and can hold what ever string you need without causing it to be interpreted as html nor html attribut because it's used in inline href tag , it was made to do this job.


It is a little bit tricky but you can select dom objects with their data attributes that contains single quotes. The trick is \\'

<div id="text" data-message="Stanley Kubrick's Oranges">Hello</div>

<script>
    var message = "Stanley Kubrick\\'s Oranges";
    $("#text[data-message='"+message+"']").fadeOut("slow");
</script>

Fiddle


If you are using Lodash, then you can use _.escape() and _.unescape(). It converts the characters "&", "<", ">", '"', and "'" in string to their corresponding HTML entities.

Reference : https://lodash.com/docs/#escape


Use the btoa method to set the data and the atob method to get it:

 $(document).data("test2",btoa('She said "<abbr title="What The F***">WTF<\/abbr>" on last nights show.">'))

Or simply dereference the string as a variable:

 var stringer = 'She said "<abbr title="What The F***">WTF<\/abbr>" on last nights show.">'

 $(document).data("test2",stringer);

References

  • HTML5 Living Standard, Web application APIs: Base64 utility methods
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜