HTTP Content-Disposition Header - ajax

I am making a successful AJAX POST request and in the response headers are the fields content-disposition: inline; filename="report.pdf" and content-type: application/pdf. From what I understand about these headers I expect the browser to display the PDF once the response is received, however the response comes back and nothing happens. Am I misunderstanding how these headers work? Am I missing a step that needs to be taken once the response is received by the browser?
$.ajax({
type: "POST",
url: "https://externalAPI.com" ,
contentType: "application/json",
data: payload,
headers: {"Authorization" : "XXXXXXXXX"}
})
I've started up a test server so that I can mess with the response headers and see if I can get anything to work. Content-Disposition:attachment; filename="pleasework.pdf" is also not working, not prompt for a file download. Here are my full response headers:
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Disposition:attachment; filename="pleasework.pdf"
Content-Type:application/pdf
Date:Wed, 15 Jul 2015 15:14:39 GMT
File-Extension:pdf
Number-Of-Pages:1
Transfer-Encoding:chunked
Vary:Origin
X-Powered-By:Express
X-XSS-Protection:0

Related

How do I GET an Amazon S3 presigned url's object from jQuery Ajax

I can find nothing on Google.
I am properly creating presigned urls because they do work if I use a browser to load the request.
However, when using the identical url from a jQuery ajax call it is failing and telling me the request signature is wrong.
PS: Here are the headers. First section is from successful browser call and second section my ajax failure.
HTTP/1.1 200 OK
x-amz-id-2: clb7J//+XLYa+XS4HJthLdDO0KxBJU02fyBt29Kr8A2TXRJXM189tGgy7bWgmoYkDzXWUhg3R5g=
x-amz-request-id: F3A8C4ED98E5443E
Date: Mon, 04 May 2015 21:53:24 GMT
Access-Control-Allow-Origin: <any valid value>
Access-Control-Allow-Methods: GET, DELETE, HEAD
Access-Control-Allow-Headers: accept, content-type
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Content-Length: 0
Server: AmazonS3
BAD AJAX:
HTTP/1.1 403 Forbidden
Access-Control-Allow-Origin: <any valid value>
Access-Control-Allow-Methods: GET, DELETE, HEAD
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-request-id: 05071412E03C4541
x-amz-id-2: xw5uMr2N/alPOR7MFMbX6fVkVEf1p30VhQKyP3yUqxYXxDq+vb5hzlsyShHwY4XhgAfLd3BCjG0=
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Mon, 04 May 2015 21:53:24 GMT
Server: AmazonS3
Here is my Ajax call:
$.ajax({
type: "GET",
url: presignedurl,
contentType: 'application/json; charset=utf-8',
cache: false,
async: true,
dataType: "text",
error: function (xhr, status, error) {
CentralScrutinizer("FetchDetails Exception: " + error);
},
success: function (payload) {
try {
$('#newTaskDetails').val(payload);
} catch (e) {
}
}
});
The specific error is:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
Again, the closest I could find was a similar SO post for a put but they merely suggested adding the following headers:
//headers: { 'Content-Type': 'application/json; charset=utf-8' },
I tried that but it made no difference.
I also used fiddler to compare the two GETs (browser versus ajax) and the only thing different I see is the jsonp callback parameter.
That shouldn't affect the signature, should it?
Here are the headers
Browser Success:
HTTP/1.1 200 OK
x-amz-id-2: clb7J//+XLYa+XS4HJthLdDO0KxBJU02fyBt29Kr8A2TXRJXM189tGgy7bWgmoYkDzXWUhg3R5g=
x-amz-request-id: F3A8C4ED98E5443E
Date: Mon, 04 May 2015 21:53:24 GMT
Access-Control-Allow-Origin: <any valid origin>
Access-Control-Allow-Methods: GET, DELETE, HEAD
Access-Control-Allow-Headers: accept, content-type
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Content-Length: 0
Server: AmazonS3
BAD AJAX:
HTTP/1.1 403 Forbidden
Access-Control-Allow-Origin:: <any valid origin>
Access-Control-Allow-Methods: GET, DELETE, HEAD
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-request-id: 05071412E03C4541
x-amz-id-2: xw5uMr2N/alPOR7MFMbX6fVkVEf1p30VhQKyP3yUqxYXxDq+vb5hzlsyShHwY4XhgAfLd3BCjG0=
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Mon, 04 May 2015 21:53:24 GMT
Server: AmazonS3
Thanks!
I found the answer.
I removed the following from the Ajax request:
contentType: 'application/json; charset=utf-8',
And it worked just fine.
I figured this out by comparing the response headers and subtracting what was common between the two.
Once I got the similarities out the only differences were content-length and content-type.
So as an experiment I simply commented out the contentType attribute and it worked.
That does not happen too often with s3 signatures and ajax. I feel I got lucky and hope this helps someone.

Web API CORS requests and browser cache

We're using web api cors requests in our application and many api calls are cacheable by the clients, i.e. browsers.
Chrome and Firefox honours the cache control headers and caches the responses as they are supposed to but Internet Explorer and Safari always performs new requests.
Controller:
[EnableCors("*", "*", "*")]
public HttpResponseMessage Get()
{
var response = Request.CreateResponse(HttpStatusCode.OK, "test");
response.Headers.CacheControl = new CacheControlHeaderValue
{
Public = true,
MaxAge = DateTime.UtcNow.AddDays(7) - DateTime.UtcNow
};
response.Headers.ETag = new EntityTagHeaderValue("\"" + Guid.NewGuid().ToString() + "\"");
return response;
}
JQuery ajax request (issued from another domain):
$.ajax({
type: 'GET',
url: 'http://next.b.se/api/tests'
}).done(function (data) {
$("#v").text("Done!");
}).error(function (jqXHR, textStatus, errorThrown) {
$("#v").text("Error");
});
Request (from fiddler):
GET http://next.b.se/api/tests HTTP/1.1
Referer: http://hitta.a.se/local.html
Accept: */*
Accept-Language: en,sv-SE;q=0.5
Origin: http://hitta.a.se
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: next.b.se
DNT: 1
Connection: Keep-Alive
Response (from fiddler):
HTTP/1.1 200 OK
Cache-Control: public, max-age=604800
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
ETag: "4bfa551b-61db-42cb-8877-25f20a0ec94d"
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: *
Date: Mon, 09 Jun 2014 10:58:12 GMT
Content-Length: 192
When loading the page hitta.a.se/local.html, from which the cross domain request is done, the first time after cleaning the browser cache all browsers (IE, CHrome, FF and Safari) makes a request to the api endpoint as expected.
When loading the page hitta.a.se/local.html the second time in a new tab and hitting return Chrome and FF gets the cached version, i.e. no request is issued to the api (as expected due to the cache-control headers) according to Fiddler and dev tools. The problem is that IE issues a new request, it does not use the cached version and it doesn't issue a conditional get using the etag and if-none-match header. I know that the api doesn't handle if-none-match requests but the problem is that the browser doesn't perform a conditional request at all.
Which is the appropriate approach if we would like IE and Safari to use the cached responses?
Notice! This question is posted on codeplex, https://aspnetwebstack.codeplex.com/discussions/548035, as well. I don't know where the web api gurus are most active!
UPDATE 2014-06-10
If we change the api call to use JSONP instead of Ajax Internet Explorer caches the response according to the cache headers.
JQuery JSONP request:
$.ajax({
type: 'GET',
url: 'http://next.b.se/api/tests',
dataType: 'jsonp',
contentType: 'text/javascript',
jsonpCallback: 'p',
cache: true
}).done(function (data) {
$("#v").text(data.v);
}).error(function (jqXHR, textStatus, errorThrown) {
$("#v").text("Error");
});
Safari still performs a new request. Any known workarounds for Safari? I.e. force Safari to honour the cache headers either on a cross domain XHR request or a JSONP request?
BR,
Max

Can't set a header using Cors and Ajax

Hello I am trying to do a http request with Basic Auth, but I can't set the header authorization and it is allowed in server.
Ajax :
$.ajax({
xhrFields: { withCredentials: true },
beforeSend: function(xhr){xhr.setRequestHeader('authorization', 'Basic cmFmmFuQHBoaWlubm92YXRpb25zLmNv=');},
url : 'http://www.vozi.dev.br/api/audio',
type: 'POST',
data: JSON.stringify(sender),
dataType: 'json',
contentType: 'application/json',
success : function(data, textStatus, jqXHR) {
//do something
}
});
Http Request Header:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,pt;q=0.6
Access-Control-Request-Headers:accept, authorization, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:www.vozi.dev.br
Origin:http://localhost:8080
Referer:http://localhost:8080/act_text.jsp
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Http Response Header:
Access-Control-Allow-Headers:accept, authorization, content-type
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:*
cache-control:no-cache
Connection:Keep-Alive
Content-Type:text/html; charset=UTF-8
Date:Wed, 14 May 2014 20:15:53 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.6 (Ubuntu)
Set-Cookie:PHPSESSID=k6gg748e47b2fv67; path=/
Transfer-Encoding:chunked
www-authenticate:Basic realm="Secured Area"
x-debug-token:5373cef9430fe
X-Powered-By:PHP/5.5.3-1ubuntu2
Error :
OPTIONS http://www.vozi.dev.br/api/audio 401 (A Token was not found in the SecurityContext.) jquery.js:8706
OPTIONS http://www.vozi.dev.br/api/audio Invalid HTTP status code 401 jquery.js:8706
XMLHttpRequest cannot load http://www.vozi.dev.br/api/audio. Invalid HTTP status code 401
I assume your having this issue with IE10 or IE11, This is not an issue with Chrome.
IE doesn't send authorization headers with OPTIONS request, so on server side if you enable Windows integrated authentication, it does reject the OPTIONS request.
I have this workaround posted on another stackoverflow question
I find out that i can't use
Access-Control-Allow-Origin:*
if I am using
withCredentials: true
Is necessary to set the origin.

Getting error when trying to get xml server response using jQuery.ajax & jsonp

I'm trying to activate jQuery.ajax() request using jsonp and I'm getting the following error:
Resource interpreted as Script but transferred with MIME type text/xml
My request is:
return $.ajax({
type: 'GET',
url: this.AgentServiceUrl + "/" + methodName,
async: false,
jsonpCallback: 'jsonCallback',
contentType: "text/xml",
dataType: 'jsonp',
success: function (json) {
console.dir(json.sites);
},
error: function (e) {
console.log(e.message);
}
});
and the response I'm getting from the server is:
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Length: 114
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 19 Jun 2013 08:43:13 GMT
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://CosmoCom.com/WebServices/TCWS/Agent">010001</string>
What can I do?
As the error message rightly says, when you mark your datatype as jsonp. it means the data you will be receiving will be script. so you cant have your contenttype as "text/xml".
Try changing it to "application/json" .
Also make sure that your service is jsonp enabled, meaning it returns data wrappped in a callback function.

CORS POST not working with Apache on FF

I'm trying to do a CORS POST call from Firefox to my Tomcat server. The Tomcat provides RESTful service. Here is my server-side return code:
ResponseBuilder rb = Response.ok( JSON.serialize(result));
rb.header("Content-Type", "text/javascript;charset=utf8");
rb.header("Access-Control-Allow-Origin", "*");
rb.header("Access-Control-Max-Age", "3628800");
rb.header("Access-Control-Allow-Methods", "GET,POST");
return rb.build();
And this is my AJAX call:
var feedQueryPOST = {"param" : someListOfParams, "timeWindow": 36000};
$.ajax({
type: 'POST',
url:"http://xxx.xxx.xxx.xxx:8080/MyWebService/getwebfeed",
contentType: "text/plain",
data: feedQueryPOST,
async: true,
success:function(json){
alert("success!");
},
error:function(e){
alert(JSON.stringify(e));
},
});
When I do a test query, I use RESTClient to inspect the header and it comes back as:
Status Code: 200 OK
Access-Control-Allow-Methods: GET,POST
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3628800
Content-Length: 318
Content-Type: text/javascript;charset=utf8
Date: Mon, 31 Dec 2012 12:02:11 GMT
Server: Apache-Coyote/1.1
But on my javascript end the callback is still going to Error with readystate = 0 and status = 0. I've been looking around for answers for a very long time to no avail. I know I might be missing something simple here. Any help is appreciated, thanks ahead of time.
Instead of contentType: "text/plain",, use dataType: 'json' and you should be fine

Resources