Nấm Lùn
Nấm Lùn

Reputation: 1275

IE and Firefox don't show UTF-8 while Chrome does

I'm using Zend Framework. I try to validate a form by using an Ajax request to an Action:

$.ajax({
        type: "POST",
        url: URL_TO_ACTION,
        data: DATA,
        success: function(result,status,xResponse) {
                var error = xResponse.getResponseHeader("error");
                    alert(error);
                },
                error: function(e){
                    alert(e);
                }
      });

In the controller, I have an Action for handling this:

public function validateAction(){
    $response = $this->_response;
    $response->setHeader(
           "error","Hãy chọn một module"
        );      
}

In IE and Firefox, it says "Hãy chá»n má»t Module" while Chrome says "Hãy chọn một module"

In the layout I do have:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

What did I do wrong here?

Upvotes: 1

Views: 631

Answers (3)

Thanatos
Thanatos

Reputation: 44256

Don't rely on HTTP headers being able to transmit anything outside of ASCII. Encode your error message in your entity body.

The long answer:

This is, in my opinion, a sucky area of the HTTP standard. According to the standard for HTTP/1.1,

HTTP header fields, which include general-header (section 4.5), request-header (section 5.3), response-header (section 6.2), and entity-header (section 7.1) fields, follow the same generic format as that given in Section 3.1 of RFC 822 [9].

RFC 822 says,

3.1.2. STRUCTURE OF HEADER FIELDS

Once a field has been unfolded, it may be viewed as being composed of a field-name followed by a colon (":"), followed by a field-body, and terminated by a carriage-return/line-feed. The field-name must be composed of printable ASCII characters (i.e., characters that have values between 33. and 126., decimal, except colon). The field-body may be composed of any ASCII characters, except CR or LF.

So, thus, HTTP headers are ASCII. However, earlier in the document, HTTP/1.1 has this to say:

The TEXT rule is only used for descriptive field contents and values that are not intended to be interpreted by the message parser. Words of *TEXT MAY contain characters from character sets other than ISO-8859-1 [22] only when encoded according to the rules of RFC 2047 [14].

TEXT           = <any OCTET except CTLs,
                  but including LWS>

(and 4.2 says headers are composed of TEXT)

any octet sequence is not the same as ASCII, and the text "MAY contain characters from character sets other than ISO-8859-1 [22] only when encoded according" seems (to me) to suggest indirectly that headers are ISO-8859-1. However, that's less important than the whole bit of that sentence:

Words of *TEXT MAY contain characters from character sets other than ISO-8859-1 [22] only when encoded according to the rules of RFC 2047 [14].

Indeed, RFC 2047 gives us a means to encode any string, in any character set, into ASCII. (RFC 2047 is how emails can contain things like Japanese in a Subject line or a From line.)

Now for the sad part: I don't think any major browsers out there implement RFC 2047. And as you've seen, Chrome treats headers as UTF-8, Firefox as ISO-8859-1. You could send it encoded in RFC 2047, or something simliar, like base64, and decode it in the javascript, but at that point, you may as well just send it in the body.

Upvotes: 1

Boris Zbarsky
Boris Zbarsky

Reputation: 35064

HTTP header value encoding has nothing to do with the encoding of your page.

In particular, header values are typically restricted to ASCII unless the spec defining the header says that RFC 2047 applies. Converting bytes to corresponding Unicode codepoints by byte-inflation (which is correct for ASCII) would give you the IE and Firefox results you see above.

Upvotes: 0

StuR
StuR

Reputation: 12218

Sounds obvious but have you cleared your browsers cache, or tried setting "cache: false" in your Ajax request?

Upvotes: 0

Related Questions