Paul Woolcock Paul Woolcock - 4 months ago 47
Ajax Question

WebKit "Refused to set unsafe header 'content-length'"

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;
}

Answer

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().

Comments