48

I am trying to implement simple xhr abstraction, and am getting this warning when trying to set the headers for a POST. I think it might have something to do with setting the headers in a separate js file, because when i set them in the <script> tag in the .html file, it worked fine. The POST request is working fine, but I get this warning, and am curious why. I get this warning for both content-length and connection headers, but only in WebKit browsers (Chrome 5 beta and Safari 4). In Firefox, I don't get any warnings, the Content-Length header is set to the correct value, but the Connection is set to keep-alive instead of close, which makes me think that it is also ignoring my setRequestHeader calls and generating it's own. I have not tried this code in IE. Here is the markup & code:

test.html:

<!DOCTYPE html>
<html>
    <head>
        <script src="jsfile.js"></script>
        <script>
            var request = new Xhr('POST', 'script.php', true, 'data=somedata',  function(data) { 
                console.log(data.text); 
            });
        </script>
    </head>
    <body>
    </body>
</html>

jsfile.js:

function Xhr(method, url, async, data, callback) {
    var x;
    if(window.XMLHttpRequest) {
        x = new XMLHttpRequest();

        x.open(method, url, async);

        x.onreadystatechange = function() {
            if(x.readyState === 4) {
                if(x.status === 200) {
                    var data = {
                        text: x.responseText,
                        xml: x.responseXML
                    };
                    callback.call(this, data);
                }
            }
        }

        if(method.toLowerCase() === "post") {
            x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            x.setRequestHeader("Content-Length", data.length);
            x.setRequestHeader("Connection", "close");
        }

        x.send(data);
    } else {
        // ... implement IE code here ...
    }
    return x;
}
  • Why don’t you let WebKit set that header field? – Gumbo Apr 12 '10 at 17:39
  • I guess i was under the impression that it was best-practices to set that field so it was consistent across browsers... –  Apr 12 '10 at 17:40
  • 4
    There are header fields that should better be set by the client/server automatically. *Content-Length* is one of them. – Gumbo Apr 12 '10 at 17:42

1 Answers1

65

it is also ignoring my setRequestHeader calls and generating its own

Yes, the standard says it must:

For security reasons, these steps should be terminated if header is [...]

  • Connection
  • Content-Length

Messing around with those could expose various request smuggling attacks, so the browser always uses its own values. There's no need or reason to try to set the request length, as the browser can do that accurately from the length of data you pass to send().

Community
  • 1
  • 1
bobince
  • 528,062
  • 107
  • 651
  • 834
  • 4
    Books particularly, Learning PHP, MySqL and JavaScript, still teach people to do this manually...I did the same thing after reading that book. –  Jun 13 '12 at 17:50
  • I need to setRequestHeader to unzip .gzip files...is this legal? –  Jun 13 '12 at 17:51
  • @Hiro: what header are you trying to set? An HTTP request will not generally decompress a .gzip resource for you; there is gzip Content-Encoding to compress a resource on the wire, but again browsers will do that for you automatically, it's not something you need to (or can) control with `XMLHttpRequest.setRequestHeader`. – bobince Jun 13 '12 at 22:49
  • I compressed my content using online Yahoo Tool ...and then all I had to change in my code was in PHP I had to do was header("Content-Encoding: gzip"); before ajax sending the zipped data back to the client....so much faster now...and just one line of code and an online tool. –  Jun 13 '12 at 23:54
  • But I think fiddling around in JS was a not correct for me...the solution was in PHP...found this after looking at about 40 google hits. –  Jun 13 '12 at 23:56
  • Completely psyched....all text content is now about 50% less....load...to network...so probably that much faster –  Jun 13 '12 at 23:57
  • 1
    jQuery.ajax request is not setting the Content-Length at all according to Chrome's network request tab in developer tools, and I can't figure out why. It tried to manually set it, but encountered this error. The request is making it to the server and being processed by an svc file, but the response is ultimately empty. This problem does not occur if I send the request from a tool like postman in chrome. It seems to be a problem with jQuery.ajax – Triynko Dec 06 '13 at 16:49
  • Hello guys I want to set the "Connection" header. Can you please let me know if there is any workaround ? – BetRob Mar 07 '14 at 06:36
  • to authorise an API call, Amazon requires to set/include the "host" header and use it in the signing process—that's fine on any server side language i Imaging—but if one is trying to do this in javascript (to develop a browser extension for example) then this is problematic. do you know of any work-around? this is the problem i have: http://stackoverflow.com/questions/28326752/aws-api-signed-post-request-with-javascript – jrgd Feb 04 '15 at 17:58
  • Hi ,I'm having a system where i have to put Cookie in header which throws same error . Could help in providing alternate solution for this. – SriMaharshi Manchem Aug 12 '16 at 06:24