1

Sorry for what maybe a very dumb javascript question (I'm from cpp/java background) but I can't find an answer to it. I'm writing a little js snippet that needs to check whether response header is present or not. That is how I do it:

var xhttp = new XMLHttpRequest();
xhttp.open("GET", "NewServlet", false);
xhttp.send();
var name = xhttp.getResponseHeader("name");
if (name === "null") {...}

Now this part with "null" I feel it is plain wrong. Really, my servlet does not set this header, so it should be null, but not stringly-typed "null". Why do I get "null" instead of null? How to check the response header is empty from ajax response, or check if the string is empty?

EDIT: The thing is, that when I put

var name = xhttp.getResponseHeader("rhrhrhrhers");
if (!name) {...}

the condition (!name) surely doesn't hold, as name is "null", not null. There's no such response header for sure, so there's some hidden type conversion going on under the hood. It is converting the null to "null" when returning the result from getResponseHeader().

EDIT2: After some investigation in console:

> var name = null;
< undefined
> name
< "null"
> if (!name) console.log("f");
< undefined
> if (name) console.log("f");
  f
< undefined

Now that doesn't make much sense to me, although I assign honest null to var it makes the sting with value "null", and condition doesn't hold.

EDIT3:

It looks that the variable called name has some special meaning in js! Though I don't know which, as in JavaScript variable name validator (https://mothereff.in/js-variables) it says it's legit.

That's what is happening in the console:

var name = null;
undefined
var test = null;
undefined
name
"null"
test
null

As you can see js interpreter somewhy deals with var name the other way than with other names (like test or whatever). The reason is still unclear to me.

Kurovsky
  • 1,081
  • 10
  • 25

3 Answers3

0

Usually in JS you simply do:

var xhttp = new XMLHttpRequest();
xhttp.open("GET", "NewServlet", false);
xhttp.send();
var name = xhttp.getResponseHeader("name");
if (!name) { 
   // no name header present
}

This will test if the name value is null (or empty string, or false). JS has type coercion, or inference for 'truthy' and 'falsey' values. So an empty string loosely evaluates to false. So does null.

Alex
  • 4,844
  • 7
  • 44
  • 58
  • "XHR requests are asynchronous" — No, that's configurable. The request being made in the question is synchronous. – Quentin Aug 07 '16 at 18:39
  • Ok removed the async bit. OP wants to test for `null` on the name variable, that's the point. – Alex Aug 07 '16 at 18:44
  • `XMLHttpRequest.getResponseHeader` returns `null` if the header is not present. Docs: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/getResponseHeader. Therefore the header is being set by the server but printing "null" as the value? – Alex Aug 08 '16 at 20:37
  • I'm the server, I don't set this header for sure. – Kurovsky Aug 08 '16 at 20:46
0

I think what you are looking for is if (xhttp.status === 0) {...}. When the status is 0 it means the response is empty. You can read more about it here: XMLHttpRequest status 0 (responseText is empty)

Community
  • 1
  • 1
Daniel Zendejas
  • 466
  • 3
  • 14
  • While it is true that the responseText will be empty (because the request failed or there was a security exception and there is no available response) when the status is 0, the reverse is not necessarily true. This doesn't matter greatly as the question was asking about an HTTP header, not the response body anyway. – Quentin Aug 07 '16 at 19:04
0

Actually, the reason was that

var name = null;

was in global scope, and that effectively called window.name property; window.name property has a setter that convert anything I pass in into a string.

Consider:

> var name = 2;
< undefined
> name
< "2"

The solution is not to touch global scope, as that is considered a bad practice. Instead:

   (function x() {
       var name = null;
       console.log(name);
    }());

This will produce the null output to console as we are in a auto-called closure this time, thus don't touch global window properties.

Kurovsky
  • 1,081
  • 10
  • 25
  • 1
    Hmm so looks like the global scope (an instance of Window function), has a property name, which you're over-writing. All JS FUnctions have a `name` property, and I guess it automatically gets converted to string. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name – Alex Aug 11 '16 at 00:42