Using jQuery's ajax method to retrieve images as a blob

前端 未结 3 2171
南旧
南旧 2020-11-22 10:36

I recently asked another (related) question, which lead to this follow up question: Submitting data instead of a file for an input form

Reading through the jQuery.aj

相关标签:
3条回答
  • 2020-11-22 10:59

    If you need to handle error messages using jQuery.AJAX you will need to modify the xhr function so the responseType is not being modified when an error happens.

    So you will have to modify the responseType to "blob" only if it is a successful call:

    $.ajax({
        ...
        xhr: function() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 2) {
                    if (xhr.status == 200) {
                        xhr.responseType = "blob";
                    } else {
                        xhr.responseType = "text";
                    }
                }
            };
            return xhr;
        },
        ...
        error: function(xhr, textStatus, errorThrown) {
            // Here you are able now to access to the property "responseText"
            // as you have the type set to "text" instead of "blob".
            console.error(xhr.responseText);
        },
        success: function(data) {
            console.log(data); // Here is "blob" type
        }
    });
    

    Note

    If you debug and place a breakpoint at the point right after setting the xhr.responseType to "blob" you can note that if you try to get the value for responseText you will get the following message:

    The value is only accessible if the object's 'responseType' is '' or 'text' (was 'blob').

    0 讨论(0)
  • 2020-11-22 11:18

    A big thank you to @Musa and here is a neat function that converts the data to a base64 string. This may come handy to you when handling a binary file (pdf, png, jpeg, docx, ...) file in a WebView that gets the binary file but you need to transfer the file's data safely into your app.

    // runs a get/post on url with post variables, where:
    // url ... your url
    // post ... {'key1':'value1', 'key2':'value2', ...}
    //          set to null if you need a GET instead of POST req
    // done ... function(t) called when request returns
    function getFile(url, post, done)
    {
       var postEnc, method;
       if (post == null)
       {
          postEnc = '';
          method = 'GET';
       }
       else
       {
          method = 'POST';
          postEnc = new FormData();
          for(var i in post)
             postEnc.append(i, post[i]);
       }
       var xhr = new XMLHttpRequest();
       xhr.onreadystatechange = function() {
          if (this.readyState == 4 && this.status == 200)
          {
             var res = this.response;
             var reader = new window.FileReader();
             reader.readAsDataURL(res); 
             reader.onloadend = function() { done(reader.result.split('base64,')[1]); }
          }
       }
       xhr.open(method, url);
       xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
       xhr.send('fname=Henry&lname=Ford');
       xhr.responseType = 'blob';
       xhr.send(postEnc);
    }
    
    0 讨论(0)
  • 2020-11-22 11:20

    You can't do this with jQuery ajax, but with native XMLHttpRequest.

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if (this.readyState == 4 && this.status == 200){
            //this.response is what you're looking for
            handler(this.response);
            console.log(this.response, typeof this.response);
            var img = document.getElementById('img');
            var url = window.URL || window.webkitURL;
            img.src = url.createObjectURL(this.response);
        }
    }
    xhr.open('GET', 'http://jsfiddle.net/img/logo.png');
    xhr.responseType = 'blob';
    xhr.send();      
    

    EDIT

    So revisiting this topic, it seems it is indeed possible to do this with jQuery 3

    jQuery.ajax({
            url:'https://images.unsplash.com/photo-1465101108990-e5eac17cf76d?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ%3D%3D&s=471ae675a6140db97fea32b55781479e',
            cache:false,
            xhr:function(){// Seems like the only way to get access to the xhr object
                var xhr = new XMLHttpRequest();
                xhr.responseType= 'blob'
                return xhr;
            },
            success: function(data){
                var img = document.getElementById('img');
                var url = window.URL || window.webkitURL;
                img.src = url.createObjectURL(data);
            },
            error:function(){
                
            }
        });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
    <img id="img" width=100%>

    or

    use xhrFields to set the responseType

        jQuery.ajax({
                url:'https://images.unsplash.com/photo-1465101108990-e5eac17cf76d?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ%3D%3D&s=471ae675a6140db97fea32b55781479e',
                cache:false,
                xhrFields:{
                    responseType: 'blob'
                },
                success: function(data){
                    var img = document.getElementById('img');
                    var url = window.URL || window.webkitURL;
                    img.src = url.createObjectURL(data);
                },
                error:function(){
                    
                }
            });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
        <img id="img" width=100%>

    0 讨论(0)
提交回复
热议问题