How to get response headers using javascript

I am trying to pull information from the Response Headers using javascript.  Can someone give me a working example of how to pull a response header by name (IE content-length) from a url like http://www.google.com?
danielledentonAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
You can do it like this - assuming the page you are querying is static i.e. not likely to generate different headers between each request

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);

Open in new window

danielledentonAuthor Commented:
How do I pull a response header by name (IE content-length) from a url like http://www.google.com?  I am looking for a working example that uses a hardcoded url and pulls just one header by name, not all the headers.
danielledentonAuthor Commented:
I am starting on an html page that has an onclick event which runs the script that pulls in the headers from another url (IE www.google.com).

How do I pull a response header by name (IE content-length) from a url like http://www.google.com?  I am looking for a working example that uses a hard-coded url and pulls just one header by name, not all the headers.
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Julian HansenCommented:
<script>
var testurl = "www.google.com";

function getHeader(url, name)
{
  var req = new XMLHttpRequest();
  req.open('GET', url, false);
  req.send(null);
  var response = req.getAllResponseHeaders().toLowerCase().trim();
  var items = response.split("\n");
  var header = [];
  for(var i = 0; i < items.length; i++) {
    var parts = items[i].split(': ');
    header[parts[0].trim()] = parts[1].trim();
  }

  var ret = header[name] || false;
  return ret;
}
var header = getHeader(testurl, 'content-length');
alert (header);
</script>

Open in new window

Julian HansenCommented:
A slightly more generic approach that gives access to all headers
<script>
var testurl = "www.google.com";

function getHeader(url)
{
  var req = new XMLHttpRequest();
  req.open('GET', url, false);
  req.send(null);
  var response = req.getAllResponseHeaders().toLowerCase().trim();
  var items = response.split("\n");
  var header = [];
  for(var i = 0; i < items.length; i++) {
    var parts = items[i].split(': ');
    header[parts[0].trim()] = parts[1].trim();
  }

  return header;
}
var headers = getHeader(testurl);
var contentLength =  headers['content-length'] || false;
alert (contentLength);
</script>

Open in new window

danielledentonAuthor Commented:
That works but it is firing off as soon as I hit the page.  I don't want it to fire until I click my link to do the onclick event which calls this function.
I tired adding the function to my link as the onclick event and passed it a URL but it just errors and the alert never appears.
Julian HansenCommented:
Using jQuery
HTML
<a href="http://www.google.com" class="someclass">Click me</a>

Open in new window

jQuery
$(function() {
 $('.someclass').click(function(e) { 
   e.preventDefault();
   // strip out the protocol prefix if it exists
   var url = $(this).attr('href').replace(/https?:\/\//,'');
   var headers = getHeader(url);
   var contentLength =  headers['content-length'] || false;
   alert (contentLength);
 });
});

Open in new window

Working sample here
danielledentonAuthor Commented:
Your code is great!! Thank you.  I am having some difficulty meshing it with my code.  I am trying to fire off a program in the backend with an onclick event.  Looks  like this:
<!DOCTYPE html>
<html>
<head>

<script>
function exportReport(){
	
	document.proficiencyForm.submit();
 
}


</script>
</head>
<body>
<form name="proficiencyForm" id="proficiencyForm" method="POST" action="https://ipaddress/exportProficiency" style="display:none">
  <input type="hidden" id="fileName" name="fileName"  />
</form>

<table>
     <tr>
      <td>      
         <a href='#' onclick='exportReport();' id="exportLink" name="exportLink">
          Export Report
        </a>
	  </td>
	</tr>		
	</table>			
</body>

Open in new window


The backend program creates a file and sends me its location in the Response Headers:
view source
Content-Length:      0
Server:      Jetty(8.y.z-SNAPSHOT)
Status:  success
file_name: J:\gapps\reports\\841594d3-557c-4641-bf60-2be5d6d225c9.xls


I am trying to grab that file name from the response header.
Julian HansenCommented:
Are you talking about the onclick from here
<a href='#' onclick='exportReport();' id="exportLink" name="exportLink">

Open in new window

Where do you get the URL that you are targeting?
danielledentonAuthor Commented:
Yes.  The url is in the form that I am submitting:
form name="proficiencyForm" id="proficiencyForm" method="POST" action="https://ip address/exportProficiency" style="display:none">
  <input type="hidden" id="fileName" name="fileName"  />
</form>

Open in new window

Julian HansenCommented:
Just explain to me how this is going to work.

You click the <a> element
It queries the URL to get the headers
Then ....?

Some questions
Why can't the URL set in the href of the <a>
What happens to the form after you submit it - trying to work out where the form submit and the retrieval of headers tie up?
danielledentonAuthor Commented:
User goes to a page and clicks a link.  The link fires off a url that fires off a program in the backend (java) which creates a report.  The program returns the file name in the response Header.  I need to grab that file name and attached it to another link so the user can download the file.  

I tried putting the url in the href that calls the program but it doesn't execute the program.  I believe I need the Post so I have the headers to pull from.

Hope I was able to give you a good explanation and answer your questions.
Julian HansenCommented:
So the form fires off the request not the link ... that is a slightly different problem. Does it have to be a form - are you sending parameters to the backend application?

A couple of questions
I need to grab that file name and attached it to another link so the user can download the file.  
Can you not simply have the backend script return the file that the user is going to download?
Is there any particular reason that the filename is coming back in the headers and not by a normal return (text / JSON)?

If the answers to above mean that you have to do it this way can you not do it like this

<a href="http://path/to/backend/script/?with=any&parameters=the&script=may&need=.">Click me</a>

Open in new window

Attach a click event to the above
Initiate an AJAX call to the URL using the code above
Get the return value from the header
Use jquery / javascript to put the value into a link and show it.

The best solution is having the script return the file - but if you have to do it the other way post back and we can look at some code - main question is - for the latter - does there have to be a form involved?
danielledentonAuthor Commented:
I am not sure if I have to use the form, but when I don't I get a 400 bad request.  If I add the address into the href and click on the link, the system is appending the web address of the server that the html page is on.  For example if my html page is on www.testserver.com, I would hit my page by going to www.testserver.com/page.html.  When I click the link it fires off the jquery and javascript but the GET is looking at www.testserver.com/ip address/proficiencyreport.  Firebug shows this a  400 bad request.  Not sure why it is appending the testserver url and not just using the other url.

Yes, eventually I will be passing parameters.

Unfortunately, I did not create the backend java code and don't have control on what is being returned.  But basically, the company does not wants a live report.  So the report gets recreated everytime a user clicks on the link.  After the report is created a new link will display that has the file name attached to it so the user can download.
Julian HansenCommented:
Actually with a form the solution is trivial.
This sample demonstrates a form that accepts parameters that are sent to a script and the resulting header is retrieved and the file_name header is extracted and turned into a link.
HTML
    <form action="t1122.php" method="post">
      <div class="form-group">
        <input type="text" name="parameter[]" class="form-control"/>
      </div>
      <div class="form-group">
        <input type="text" name="parameter[]" class="form-control" />
      </div>
      <input type="submit" />
    </form> 
    <a href="" id="target" style="display:none">Download link<

Open in new window

jQuery
<script>
$(function() {
  $('form').submit(function() {
    $.ajax({
    url: $(this).attr('action'),
    data: $(this).serialize(),
    type: 'post'
  }).done(function(resp, status, hdr) {
    $('#target').attr('href', hdr.getResponseHeader('file_name')).show();
  });
  return false;
  });
});
</script>

Open in new window

The PHP file (code below for reference) takes the parameters submitted and uses them to create a file name which is then returned in the response header value file_name
jQuery does all the heavy lifting for us - by submitting the form via AJAX - we get a hdr parameter in the success function that we can use to query the header directly without having to parse the string into key value pairs - much simpler than the code above.
Working sample here
danielledentonAuthor Commented:
Your code is awesome!!  I am trying to incorporate it into my code.  I changed the action of the form from your php page to my ip address (https://ip address/exportProficiency).  However, when I click the submit button it does post but it doesn't stay on my Html page, it goes to the url ( (https://ip address/exportProficiency).

What am I doing wrong?
danielledentonAuthor Commented:
If this helps to explain more the ip address that i am using is a camel call to a jetty endpoint that fires off the java code.  (This is coming from the engineer who wrote that code)
Julian HansenCommented:
However, when I click the submit button it does post but it doesn't stay on my Html page, it goes to the url ( (https://ip address/exportProficiency).

What am I doing wrong?
This is usually because the code to stop the default submit action is failing (or not present). Line 11 of the code I posted contains the line

return false;

This tells the submit process to halt and not proceed with the default submit action (submitting the form).
Either the return is missing or there is a javascript error that is occurring before the submit which is causing the script to terminate before reaching the return.

Check your console for errors - you can also do this to prevent the form from submitting

$('form').submit(function(e) {
  e.preventDefault();
  ...
});

Open in new window

danielledentonAuthor Commented:
Here is my code.  I check the console and there are no errors.  The java program in the backend is fired off and the header in the Post shows the file_name.  But it is still going to the ip address instead of staying on the html page.
What am I missing?

    <!doctype html>
    <html>
    <head>
    <title>Test</title>
   
    <style type="text/css">
    </style>
    </head>
    <body>
    <div class="wrapper">
      <header>
        <div class="container">
        
        </div>
      </header>
      <div class="container">
       
    <form action="https://ip address/exportProficiency" method="POST">
          <div class="form-group">
            <input type="hidden" name="parameter[]" class="form-control" value="regions"/>
          </div>
          
          <input type="submit" />
        </form> 
        <a href="" id="target" style="display:none">Download link</a>
    </div>
    </div>
    
    <script src="https://code.jquery.com/jquery.js"></script>
     
 
   
    <script type="text/javascript]">
    $(function() {
     
      $('form').submit(function() {
     
        $.ajax({
          url: $(this).attr('action'),
          data: $(this).serialize(),
          type: 'post'
		  
      })
      
      .done(function(resp, status, hdr) {
       
	  alert("got here")
        $('#target').attr('href', hdr.getResponseHeader('file_name')).show();
      });
      return false;
      });
    });
    </script>
    </body>
    </html>

Open in new window

Julian HansenCommented:
You gonna kick yourself :)

<script type="text/javascript]">
                             ^

Open in new window

The type is not really required you can just do
<script>
danielledentonAuthor Commented:
OMG, duh.  When I didn't add a type in the script tag, firebug was showing $ function as an error and stated it is as undefined.  That is why I put the type in the script tag originally.

I took the type out and reran the page.  It no longer goes to the url but still is not pulling the header. I see that it is executing the post to my url in Firebug and I can see the filename in the header, but for some reason I am not pulling it in.
Julian HansenCommented:
Try using this as your action URL for your form.

http://www.marcorpsa.com/ee/t1122.php

I have tested your code against this and it works.

However here is what might be tripping you up - because the script request is cross domain it requires that CORS be enabled. This is done by sending the header
Access-Control-Allow-Origin: *

Open in new window

This is not enough - you have to send another header to explicitly expose the file_name header like this
Access-Control-Expose-Headers: file_name

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
danielledentonAuthor Commented:
Do I put that in my jquery code or the backend java code?
Julian HansenCommented:
That has to go in the backend. Because of cross domain scripting security the sending entity has to control what the receiving entity can see - so in your server (java code) you have to expressly say you want to expose that header.

I would check your script against the URL above - if that works then you know your script is correct and you can then change the server code.
danielledentonAuthor Commented:
I switched out my url for yours.  It erred at first because of blocked mixed content.  ( You url is http and my page is https).  I changed your url to https and it went through but aborted the Post.  I am still going to have my coworker try the Access control code from above.
danielledentonAuthor Commented:
Thank you for your help.  Adding the Access control to the backend code allowed me to pull in the header.  After adding that, all of your solutions worked perfectly.  I greatly appreciate the help.
Julian HansenCommented:
You are most welcome.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.