16

This is an offshoot of this question: Chrome counts characters wrong in textarea with maxlength attribute


In that question it was found that Javascript counts carriage returns are one character when in fact it is two (\r\n), why is that?

Test Fiddle: http://jsfiddle.net/maniator/E527z/

Community
  • 1
  • 1
Naftali
  • 144,921
  • 39
  • 244
  • 303
  • 4
    Here's your answer with evidence: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#concept-textarea-api-value –  Apr 05 '12 at 15:47

1 Answers1

26

For reasons unknown, jQuery always converts all newlines in the value of a <textarea> to a single character. That is, if the browser gives it \r\n for a newline, jQuery makes sure it's just \n in the return value of .val(). (Actually the reason probably isn't "unknown"; it's probably to normalize the results across browsers, because IE reports newlines as being 2 characters long.)

Chrome and Firefox both count the length of <textarea> tags the same way for the purposes of "maxlength".

However, the HTTP spec insists that newlines be represented as \r\n. Thus, jQuery, webkit, and Firefox all get this wrong. When the field is posted, webkit and Firefox correctly add the newlines!

The upshot is that "maxlength" on <textarea> tags is pretty much useless if your server-side code really has a fixed maximum size for a field value.

Edit This is still an issue in 2015 - at least on Chrome 45.0.2454 and IE 11.0.9600.

Ram
  • 173
  • 2
  • 11
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 3
    "The upshot is that "maxlength" on – wired_in Oct 29 '14 at 20:54
  • 1
    @wired_in no, because the browser maintainers are weird people and they don't seem to understand the whole point of `maxlength` (my personal opinion). I've logged bugs against Firefox and WebKit and the amount of bizarre uninformed pushback I've gotten is amazing. The `maxlength` implementations check the length as returned by `.value`, which is to say the length *without* the CR characters that are introduced when the form is posted. I've moved on and I'll just stick with my JavaScript solution. – Pointy Oct 30 '14 at 04:29
  • 1
    "The `maxlength` implementations check the length as returned by `.value`, which is to say the length without the CR characters" - It's the other way round. `maxlength` counts the CR+LF (which JavaScript does not) - as demonstrated by the above jsfiddle and in the linked question. So, `maxlength` is actually correct with respect to server-side code, it's only a "problem" if you are also processing this with client-side JavaScript. – MrWhite Sep 05 '15 at 21:56
  • @w3d things may be different now since the last time I tested this, but in the past it was definitely the case that (other than IE, oddly) browsers reported the value without the carriage returns, and that was what the `maxlength` thing checked - there's extensive discussion in bugs I logged back then with both Mozilla and the WebKit people. – Pointy Sep 05 '15 at 22:46
  • @w3d yes Firefox and Chrome both seem to do this correctly now. – Pointy Sep 05 '15 at 22:47
  • 1
    @w3d wait, I take that back - see [this extremely simple jsfiddle](http://jsfiddle.net/tpfe4n1y/). Type stuff, including hard returns, and see how many characters Firefox lets you type. Firefox 40.0.3 is clearly treating hard returns as 1 character, not 2. – Pointy Sep 05 '15 at 22:55
  • Confirmed: Chrome (current: 47.0.2526.111, and Canary: v50.0.2525.0) still includes `\r` and `\n` when considering `maxlength`, and this appears to actually help with HTTP standard to POST newlines as `\r\n` (browser input matches server). FireFox and Internet explorer (10 and up, where HTML5 `textarea maxlength` support was introduced) do not consider `\r` when enforcing `maxlength` and in their case the problem is that if the server is following same rules to truncate data (which is good idea when sanitizing inputs because `maxlength` is easy to bypass) then the server input does not match. – nothingisnecessary Jan 20 '16 at 21:07
  • 1
    I've updated the JS fiddle to update faster/on-the-fly as you type http://jsfiddle.net/E527z/35/ but I don't see any browser treating textarea linebreaks as 2 characters (`\r` + `\n`) in JavaScript or when applying the `maxlength` attribute (including Chrome up to 65/67)... when submitting to the server, the linebreaks are "doubled" as `\r\n` as expected by the specs. – scunliffe Apr 03 '18 at 15:10
  • @scunliffe I gave up trying to get either Chrome or FF devs to understand the issue; in some ways it's broken all the way back to the spec, because ultimately the devs (both groups) ended up waving some spec around. – Pointy Apr 03 '18 at 15:26
  • @Pointy I'm in the camp that a single `\n` in the browser world is fine, and that all backend solutions need to coerce `\r\n` into `\n` *if* that is what the backend/DB desires. Certain parts of the history of the web baffle me. I get the `/` vs. \ Unix vs. Microsoft war in the URL path... but IMHO, the `\r\n` was a mistake. – scunliffe Apr 03 '18 at 15:30
  • 1
    @scunliffe I don't understand why the `\r` is mandated either, so getting rid of that would be fine too. It's just a weird situation. – Pointy Apr 03 '18 at 15:36
  • "For reasons unknown" - this post seems to go some way to explaining: https://github.com/jquery-validation/jquery-validation/issues/2101#issuecomment-344771526 – gbro3n Jan 13 '21 at 20:29
  • @gb2d thanks but I gave up arguing with the pedants who clearly have never actually implemented a real web application a long time ago :) – Pointy Jan 13 '21 at 20:36