7

On a get response I have content-disposition: attachment;filename=f.csv and I need to download content of this file on the page .
On a $.ajax request I have an error. How can I get content of file using jQuery ajax(or get)?
UPD

error: function( jqXHR, textStatus, errorThrown ) {
  console.log( jqXHR, textStatus, errorThrown );
}  

get

Object {
    ...
    readyState 0
    responseText ""
    status 0
    statusText "error"
}, error,  

UPD 2
I found a jquery.fileDownload plugin, but it shows browser's window with save or open dialog, like this: save/open dialog
But I need to get file content.
I'm no need to download file on computer.

UPD 3
Full code listing:

$.ajax( {
    url: link,
    crossDomain: true,
    dataType: "text",
    success: function( data, textStatus, jqXHR ) {
        alert( data );
    },
    error: function( jqXHR, textStatus, errorThrown ) {
        console.log( jqXHR, textStatus, errorThrown );
    }
} );  

File generates by another service and I can't change it.
UPD 4
First of all I'l try to get json data from another domain like this:

$.ajax( {
    url: link,
    async: true,
    cache: true,
    dataType: "jsonp",
    crossDomain: true,
    type: "GET",
    jsonp: "finance_charts_json_callback",
    jsonpCallback: "finance_charts_json_callback",
    error: function( jqXHR, textStatus, errorThrown ) {
        console.log( jqXHR, textStatus, errorThrown );
    },
    success: function( data, textStatus, jqXHR ) {
        console.log( data );
    }
} );  

link looks like http://chartapi.finance.yahoo.com/instrument/1.0/a/chartdata;type=quote;ys=2012;yz=2;ts=1234567890/json?finance_charts_json_callback=finance_charts_json_callback

And it's response headers:

HTTP/1.1 200 OK
Date: Wed, 30 Apr 2014 12:01:08 GMT
P3P: policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO ... GOV"
Cache-Control: public
Expires: Thu, 01 May 2014 00:32:18 GMT
Last-Modified: Wed, 30 Apr 2014 00:32:18 GMT
Content-Type: text/javascript; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding,X-Ssl
Age: 0
Via: http/1.1 yts39.global.media.ir2.yahoo.com (...)
Server: ATS
Connection: keep-alive  

All works fine.

When I try to get file from another server there it's response headers:

HTTP/1.1 200 OK
Cache-Control: no-cache
Date: Wed, 30 Apr 2014 12:09:01 GMT
Pragma: no-cache
Content-Type: text/csv
Expires: -1
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
content-disposition: attachment;filename=export.csv
Content-Encoding: gzip
Vary: Accept-Encoding
Engineer2021
  • 3,288
  • 6
  • 29
  • 51
ostapische
  • 1,572
  • 2
  • 12
  • 26
  • And what is that error? – t.niese Apr 28 '14 at 08:27
  • @t.niese see **UPD** section – ostapische Apr 28 '14 at 08:35
  • possible duplicate of http://stackoverflow.com/questions/4545311/download-a-file-by-jquery-ajax – setec Apr 30 '14 at 09:07
  • @setec thanks for comment, I see this question and answers, but there is no what I need. See **UPD 2** section. – ostapische Apr 30 '14 at 11:18
  • then don't send the file via content disposition. use simple json response. – streak Apr 30 '14 at 11:22
  • @ostapische, can you show the full ajax code, including all parameters that you pass to `$.get` or `$.ajax`. – MrCode Apr 30 '14 at 11:24
  • Is not this browser thing? I think that you could not send the file content to show up in the browser window. It depends on browser settings. Am I right? – t00thy Apr 30 '14 at 11:26
  • @streak I'm getting file from another service and can't change type of response. – ostapische Apr 30 '14 at 11:54
  • @MrCode Yeah, sure, see **UPD 3** - it's simple request. – ostapische Apr 30 '14 at 11:54
  • @t00thy I don't know... If I can't, can you explain why? Or what settings I must change? – ostapische Apr 30 '14 at 11:55
  • 1
    @ostapische is `link` on another domain? If so, it will only work if the server supports CORS by sending the `Access-Control-Allow-Origin: *` header. – MrCode Apr 30 '14 at 11:56
  • @MrCode yeah, to another. See **UPD 4**. When I get data from *yahoo* server - all works fine without `Access-Control-Allow-Origin` header. I post headers from another service, that generates file, he is not connected to *yahoo*, it's another site, and he also don't send `Access-Control-Allow-Origin` header, but I can't get file content and have an error. – ostapische Apr 30 '14 at 12:16
  • @ostapische If possible, can post url to `.csv` document ? – guest271314 May 03 '14 at 16:23
  • @guest271314 Something like [that](http://finviz.com/export.ashx) – ostapische May 04 '14 at 08:11
  • @ostapische Has a solution to meet the requirement been achieved ? Is utilization of php an available option to fulfill requirement ? Thanks – guest271314 May 12 '14 at 04:51
  • @guest271314 I can use only clientside javascript. – ostapische May 12 '14 at 16:55
  • @ostapische Perhaps challenging utilizing only client side js. Was able to achieve requirement a) minimal php piece; b) client (or, maintainer) fetches file, then uploads file back to same html document for viewing (`html`, `js` only utilizing `input[type=file]`); c) maintainer fetch file 1st, then display using option b); d) try utilizing chromium browser remote debug option (devtools, `phantomjs`) to fetch file then relay file to client for viewing; e) custom `XMLHttpRequest`, jquery `ajax`. Tried a), b), c), appear work ok; still trying pure js solutions. Good question. Thanks for sharing – guest271314 May 13 '14 at 00:43

3 Answers3

2

It is not possible to get the file content because it resides on a different domain, content-disposition data is not compatible with JSONP and the server doesn't support CORS (Cross Origin Resource Sharing) via the Access-Control-Allow-Origin header.

Your first request works because the server is responding with JSONP. However your content-disposition request is receiving raw data (which is not possible to access without CORS).

JSONP works by requesting the resource as a <script>, the server responds with a JavaScript function call, passing the data as the argument. So when you receive the script, the browser executes it and you can access the data in the function.

The content-disposition request works by having the sever output the raw content of the file, and there is no JavaScript function call like in JSONP, so although the browser receives the data, it will not allow you to access it.

The only two possible solutions are:

  • Ask the server administrator to enable CORS.
  • Proxy your ajax request through a server side script on the same domain as your JavaScript, which will not be subject to the same cross domain restrictions because it will be a server to server request.
MrCode
  • 63,975
  • 10
  • 90
  • 112
  • I found that [XMLHttpRequest Level 2](http://dev.w3.org/2006/webapi/XMLHttpRequest-2/) in modern browsers have `responseType` field, like a `blob` or `arraybuffer`. Maybe I can use it? – ostapische Apr 30 '14 at 13:31
  • Unfortunately not, the browser is stopping it for security reasons. It would be a major security flaw if it allowed you to access the content. – MrCode Apr 30 '14 at 13:42
0

Edit, updated

Try

$(function() {
    $.getJSON("https://query.yahooapis.com/v1/public/yql?q=select"
              +"* from csv where url='http://finviz.com/export.ashx?'"        
              +"&format=json&diagnostics=true&callback=?"
      , function (data, textStatus, jqxhr) {
        $.each(data.query.results.row, function (index, value) {
            jqxhr.promise()
            .done(function () {
                    $("<li>", {
                      "text": value.col2 + " " + value.col8
                    })
                    .css("padding", "8px")
                    .appendTo("ol");
            })
            .always(function () {
                if (index === 4999) {
                  console.log(data.query
                            , data.query.diagnostics.warning
                            , data.query.results.row.length
                            , index
                            , $("li").length);
                };
            });
        });
    });
});

jsfiddle http://jsfiddle.net/guest271314/yxfEp/

guest271314
  • 1
  • 15
  • 104
  • 177
  • "You have reached the maximum number of items which can be returned in a request". It works, but not all rows shows, only first 5000, anyway thanks, it's the best solution I think. – ostapische Jul 07 '14 at 09:29
  • One approach to fetch entire file could be to visit site, then perform `XMLHttpRequest` at site, utilizing `arraybuffer` response type, as mentioned at comments; then read response utilizing `File API`. Would then need to `$.post()` the data to another page. Tried approach utilizing an `iframe` with site as `src`; revert to cross-domain issues; though perhaps achievable. fwiw, entire file comprises approximately 7,000+ entries. Thanks. – guest271314 Jul 07 '14 at 13:56
0

just an idea. But have you tried to generate a different content on the server side?. like deserializing these csv into objects (in whatever language you re using) and then just return the objects setialized into json content.