Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: gh-pages
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 135 lines (101 sloc) 5.304 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
<!DOCTYPE html>
<html>
  <meta charset="utf-8">
  <title>What is the Rails _utf8/_snowman tag?</title>
  <style type="text/css" media="screen">
    body {
     background-color: #eee;
     color: #666;
     font: 10pt/1.6em "Lucida Grande", "Lucida Sans Unicode", sans-serif;
     margin: 2em auto;
     width: 740px;
    }

    h1 {
      color: black;
      font-size: 1.4em;
      margin: 2em 0 0.5em;
    }

    article {
     display: block;
     background-color: white;
     border-radius: 4px;
     -moz-border-radius: 4px;
     -webkit-border-radius: 4px;
     -moz-box-shadow: 0 2px 5px rgba(0,0,0,0.3);
     -webkit-box-shadow: 0 2px 5px rgba(0,0,0,0.3);
     padding: 40px;
    }
    
    a { text-decoration: none; }
    
      a:link, a:visited { color: #1F66C7; }
      a:hover { color: #CF470F; }

    code {
      color: black;
      line-height: 1em;
      font-family: Monaco, monospace;
    }
    
    .lesser { font-size: 0.8em; }
    
    p { margin: 1em 0; }
    
    em { font-style: italic; }
    
    strong { font-weight: bold; }

    #example {
      text-align: center;
      margin-bottom: 4em;
    }
    
      #example code {
        background-color: transparent;
        color: #999;
        font-size: 2em;
        display: block;
      }
    
    #frosty {
      color: black;
      font-size: 20em;
      line-height: 1em;
    }
    
    pre {
      background-color: #eee;
      padding: 1em;
      overflow: auto;
    }
    
    pre code {
      color: #666;
      background-color: transparent;
    }
    
    footer {
      display: block;
      font-size: 1.2em;
      text-align: center;
      padding-top: 1em;
    }

  </style>
  <body>
    
    <article>
      <section id="example">
        <div id="frosty">&#9731;</div>
        <code>&amp;#9731;</code>
      </section>
    
      <h1>What's with the <code>_utf8</code>/<code>_e</code>/<code>_snowman</code> tag in Rails 3?</h1>
      
      <p>The <code>_utf8</code> input tag forces Internet Explorer to properly respect your form's character encoding.</p>
      
      <p>Rails uses the <code>accept-charset</code> attribute in your <code>form</code> element to let the server know that it should be able to deal with unicode characters (think of a user searching for <em>caf&eacute;</em>). Here's an example:</p>
      
      <pre><code>&lt;form <strong>accept-charset='UTF-8'</strong> action='/posts' id='create-post' method='post'&gt;
  &hellip;
&lt;/form&gt;</code></pre>
      
      <p>Unfortunately, IE5-IE8 will not look at <code>accept-charset</code> unless at least one character in the form's values is not in the page's charset. Since the user can override the default charset at the browser level, Rails provides a hidden input containing a unicode character (Rails' default encoding is UTF-8), forcing IE to look at <code>accept-charset</code>. The unicode character is a snowman. Here's what the tag looks like:</p>
      
      <pre><code>&lt;input name="_utf8" type="hidden" value="&amp;#9731;" /&gt;</code></pre>
      
      <p>You can safely ignore <code>params[:_utf8]</code> in your Rails application.</p>
      
      <p><b>Note:</b> The <code>_utf8</code> tag might be rendered as <code>_e</code> or <code>_snowman</code> depending on how recent your edge version of Rails is.</p>
        
      <h1>Why does it matter? What's the impact on my users?</h1>
      
      <p>From <a href="http://yehudakatz.com/">wycats</a>, author of the patch:</p>
      
      <blockquote>
        <p>This bug exists in IE5, IE6, IE7, and IE8. If the user switches the browser's encoding to Latin-1 (to understand why a user would decide to do something seemingly so crazy, check out <a href="http://www.google.com/search?sourceid=chrome&amp;ie=UTF-8&amp;q=diamond+with+a+question+mark+in+it">this google search</a>), any form submission will be sent in Latin-1.</p>
        
        <p>This means that if a user searches for "Ch&eacute; Guevara", it will come through incorrectly on the server-side. In Ruby 1.9, this will result in an encoding error when the text inevitably makes its way into the regular expression engine. In Ruby 1.8, it will result in broken results for the user.</p>

        <p>By creating a parameter that can only be understood by IE as a unicode character, we are forcing IE to look at the <code>accept-charset</code> attribute, which then tells it to encode all of the characters as UTF-8, even ones that can be encoded in Latin-1.</p>

        <p>Keep in mind that in Ruby 1.8, it is extremely trivial to get Latin-1 data into your UTF-8 database (since NOTHING in the entire stack checks that the bytes that the user sent at any point are valid UTF-8 characters). As a result, it's extremely common for Ruby applications (and PHP applications, etc. etc.) to exhibit this user-facing bug, and therefore extremely common for users to try to change the encoding as a palliative measure.</p>
      </blockquote>
      
      <footer>
        <a href="http://github.com/rails/rails/commit/25215d7285db10e2c04d903f251b791342e4dd6a">See the initial patch on GitHub...</a>
        <a href="http://github.com/rails/rails/commit/c49144b2f7b2cb9b59ea3a9cddd69de47f268ae6" class="lesser">(and subsequent change)</a>
      </footer>
      
    </article>
    
  </body>
</html>
Something went wrong with that request. Please try again.