How to set a header for a HTTP GET request, and trigger file download?

前端 未结 5 1258
不思量自难忘°
不思量自难忘° 2020-11-27 03:02

Update 20140702:

  • The solution
  • Detailed answer as a blog post

(but I\'m marking one of the other answers as accepted in

5条回答
  •  情深已故
    2020-11-27 03:28

    There are two ways to download a file where the HTTP request requires that a header be set.

    The credit for the first goes to @guest271314, and credit for the second goes to @dandavis.

    The first method is to use the HTML5 File API to create a temporary local file, and the second is to use base64 encoding in conjunction with a data URI.

    The solution I used in my project uses the base64 encoding approach for small files, or when the File API is not available, otherwise using the the File API approach.

    Solution:

            var id = 123;
    
            var req = ic.ajax.raw({
                type: 'GET',
                url: '/api/dowloads/'+id,
                beforeSend: function (request) {
                    request.setRequestHeader('token', 'token for '+id);
                },
                processData: false
            });
    
            var maxSizeForBase64 = 1048576; //1024 * 1024
    
            req.then(
                function resolve(result) {
                    var str = result.response;
    
                    var anchor = $('.vcard-hyperlink');
                    var windowUrl = window.URL || window.webkitURL;
                    if (str.length > maxSizeForBase64 && typeof windowUrl.createObjectURL === 'function') {
                        var blob = new Blob([result.response], { type: 'text/bin' });
                        var url = windowUrl.createObjectURL(blob);
                        anchor.prop('href', url);
                        anchor.prop('download', id+'.bin');
                        anchor.get(0).click();
                        windowUrl.revokeObjectURL(url);
                    }
                    else {
                        //use base64 encoding when less than set limit or file API is not available
                        anchor.attr({
                            href: 'data:text/plain;base64,'+FormatUtils.utf8toBase64(result.response),
                            download: id+'.bin',
                        });
                        anchor.get(0).click();
                    }
    
                }.bind(this),
                function reject(err) {
                    console.log(err);
                }
            );
    

    Note that I'm not using a raw XMLHttpRequest, and instead using ic-ajax, and should be quite similar to a jQuery.ajax solution.

    Note also that you should substitute text/bin and .bin with whatever corresponds to the file type being downloaded.

    The implementation of FormatUtils.utf8toBase64 can be found here

提交回复
热议问题