Side navigation
#13223 closed bug (fixed)
Opened January 15, 2013 11:08PM UTC
Closed May 09, 2013 07:04PM UTC
Last modified September 23, 2014 02:20PM UTC
jQuery 1.9 + client-side template = “Syntax error, unrecognized expression”
Reported by: | spizder@gmail.com | Owned by: | |
---|---|---|---|
Priority: | high | Milestone: | 1.10 |
Component: | core | Version: | 1.9.0 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
I just updated jQuery from 1.8.3 to 1.9, and it started crashing all of a sudden.
This is my Mustache template:
<script type="text/template" id="modal_template"> <div>hello</div> </script>
This is how I read it:
modal_template_html = $("#modal_template").html();
This is how I transform it into jQuery object (I need to use jQuery methods on it):
template = $(modal_template_html);
... and jQuery crashes!
Error: Syntax error, unrecognized expression: <div>hello</div>
slice.call( docElem.childNodes, 0 )[0].nodeType;
jquery-1.9.0.js (line 3811)
However, if I declare template as a plain text variable, it starts working again:
modal_template_html = '<div>hello</div>';
Attachments (0)
Change History (35)
Changed January 15, 2013 11:11PM UTC by comment:1
_comment0: | You probably have whitespace or other junk in the string. \ \ http://stage.jquery.com/upgrade-guide/1.9/#jquery-htmlstring-versus-jquery-selectorstring \ → 1358359548996745 |
---|---|
resolution: | → notabug |
status: | new → closed |
Changed January 16, 2013 10:05AM UTC by comment:2
_comment0: | Same problem here I guess: \ \ $(' <br />') don't work \ $('<br />') is ok. \ \ http://jsfiddle.net/charlesbourasseau/tuJ87/ → 1358331103706216 |
---|
I edited after I read the comment of dmethvin, thanks.
Changed January 16, 2013 01:29PM UTC by comment:3
Not that I want to retreat or anything, but surely whitespace at the beginning of an otherwise perfectly fine piece of HTML should be treated as HTML, right? dmethvin, perhaps we went a bit too far on "looks like HTML" strictness? I know we can have this debate for years, and the answer is "use $.parseHTML()", but just a fleeting thought.
Changed January 16, 2013 06:19PM UTC by comment:4
My thinking was that if there is whitespace then the text is probably being pulled in from some non-literal-string source such as it is here. That is exactly the case where we want to make people think about the fact that the string they are processing can contain scripts and therefore is a vector for XSS or other attacks. Although $.parseHTML()
does not provide perfect protection it does allow control over whether script tags run.
Also, if we always pass the string through $.trim()
or an equivalent regex for every use of $()
it's more overhead. For a small string like " <br/>"
it's nothing but again with a template that might be 100KB it would be better not to do that.
Changed February 03, 2013 09:14PM UTC by comment:7
Seriously?
Instead of
$(' <div> ');
it's now
$($.parseHTML(' <div> '.trim()));
What was the reason behind crippling a great utility function? Is there anything gained from this?
Changed February 03, 2013 10:03PM UTC by comment:8
Replying to [comment:7 andreas.korth@…]:
What was the reason behind crippling a great utility function? Is there anything gained from this?
We gained the ability to reliably differentiate $( selector )
from $( html )
, fixing #11290 and other "selector interpreted as HTML" bugs and getting a performance increase in the process. If you know you might have leading whitespace but don't care about it, just "uncripple" like $( $.trim(template) )
. For anything more complex, yeah, you should be explicit about requesting HTML parsing (in which case the trim
is probably unnecessary, if not undesirable).
Changed February 10, 2013 09:41PM UTC by comment:10
component: | unfiled → core |
---|
Changed February 10, 2013 09:45PM UTC by comment:11
#13429 is a duplicate of this ticket.
Changed February 19, 2013 07:36PM UTC by comment:12
#13476 is a duplicate of this ticket.
Changed February 24, 2013 11:20PM UTC by comment:13
#13512 is a duplicate of this ticket.
Changed March 07, 2013 11:05PM UTC by comment:14
#13582 is a duplicate of this ticket.
Changed March 11, 2013 01:39PM UTC by comment:15
I still say we should just trim it.
Changed March 11, 2013 01:39PM UTC by comment:16
#13591 is a duplicate of this ticket.
Changed March 11, 2013 07:40PM UTC by comment:17
The amount of duplicates pretty much calls for a solution on the jQuery-side ...
Changed March 11, 2013 07:49PM UTC by comment:18
We're talking about a handful of reports over 2 months following a major release. The code is easy to change on the user's end, and the confusion will die down over time.
Changed March 11, 2013 08:58PM UTC by comment:19
People are not normally used to the idea that adding new line or indentation to their template for clarity purposes will lead to some nasty error message.
Frankly, current behavior is not logical (who would have thought THAT?), very frustrating and extremely hard to debug. Hours and hours will be wasted before a reasonable person will figure out that a newline character is to blame.
So if it looks like a bug, feels like a bug, and behaves like a bug - it is probably a bug.
Changed March 11, 2013 09:30PM UTC by comment:20
For 1.10 we're planning to disable running scripts by default, which will solve the problem from the other direction and coincidentally allow more spaciness. Anyone who took our advice and used $($.parseHTML(html, document, true))
to run html+scripts will be fine with the new setup as well.
Changed March 12, 2013 02:28AM UTC by comment:21
@dmethvin What do you mean by "disable running scripts by default"?
In regards to wasting hours: I (and am absolutely "unproud" of saying that), invested 6,5 hours debugging the issue - for the first half investigating my code.
Remember that it's unlikely someone is encountering the issue while typing strings explicitly. It's more likely that the markup is the result of (a lot of) server-side logic.
At the end it's surprising, that the simplest part (a declaration) actually is at fault.
Lesson learned: Always expect strange bugs in even the most established resources.
I'll try the recommended logic. For now I solved it by calling three more methods server-side. - Which is definitely far from causing a "performance gain".
Changed March 12, 2013 12:54PM UTC by comment:22
What do you mean by "disable running scripts by default"?
The current plan for 1.10 is this:
// This can come from an evil person var html = "<p>hello</p><script src='bad.js'></script>" // Won't load/run the script in 1.10 $(html).appendTo("body"); // Loads and runs script $($.parseHTML(html, document, true)).appendTo("body");
If your template does not have script it will work as it did in 1.8.3. If it has script you'll need to opt into running it.
Lesson learned: Always expect strange bugs in even the most established resources.
I'd have a bit more sympathy if people experiencing this problem had reported this during the beta. If you want jQuery to be bug-free and for design decisions to break your way, you'll need to participate in the beta tests and see how *your* code fares.
Changed April 19, 2013 01:16PM UTC by comment:23
#13790 is a duplicate of this ticket.
Changed April 19, 2013 08:40PM UTC by comment:24
Having
$(html)
perform a trim on the html string before further processing would not affect the 1.9 improvements to that function's security, and would fix plugins that this change has broken (for example, waypoints-infinite).
Changed April 29, 2013 09:56PM UTC by comment:25
#13836 is a duplicate of this ticket.
Changed April 30, 2013 04:22PM UTC by comment:26
resolution: | notabug |
---|---|
status: | closed → reopened |
Changed April 30, 2013 04:24PM UTC by comment:27
milestone: | None → 2.0.1 |
---|---|
priority: | undecided → high |
status: | reopened → open |
The team has decided to allow leading whitespace here (and possibly trailing).
Changed April 30, 2013 07:57PM UTC by comment:28
I would throw my vote towards allowing both leading and trailing whitespace, as I often leave a trailing newline at the end of my HTML templates.
Changed May 02, 2013 08:26PM UTC by comment:29
So is this going into 1.10/2.0.1, or is it going into 1.11/2.1? We'll be making the rules tighter for the latter (no scripts), but should we loosen them in the meantime?
I ask since 1.10b1 is imminent...
Changed May 02, 2013 08:50PM UTC by comment:30
@dmethvin: I think both. We can simply match leading whitespace like we did before and still not allow scripts.
Changed May 06, 2013 04:24PM UTC by comment:31
milestone: | 2.0.1 → 1.10 |
---|
Changed May 09, 2013 07:04PM UTC by comment:32
resolution: | → fixed |
---|---|
status: | open → closed |
Fix #13223. Re-allow leading space in HTML. Close gh-1264.
(cherry picked from commit 00eafdf028f7730665ce1c05ab44e3f0bc80fbc2)
Changeset: 9fdbc8bf33418f7b3a3a88df9a04ffee53c8dc66
Changed July 03, 2013 07:50AM UTC by comment:33
So, what is the reason behind fixing this in 1.10 and leaving it as is in 1.9? Wasn't the defect opened in 1.9 and should be fixed in the same version?
Not all can just upgrade, see JQM:
jQuery Mobile 1.3 supports jQuery 1.7.0 to 1.9.1
So, my question is - when will this be fixed in 1.9?
As a side note, I didn't expect such a huge blunder from jQuery team - this probably breaks code on thousands of sites that use client-side templates.
Thanks.
Changed July 03, 2013 12:43PM UTC by comment:34
#14097 is a duplicate of this ticket.
Changed September 23, 2014 02:20PM UTC by comment:35
Can this fix be applied to 1.9.x branch, since 1.10 is still in beta?
You probably have whitespace or other junk in the string.
http://jquery.com/upgrade-guide/1.9/#jquery-htmlstring-versus-jquery-selectorstring