最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to be able to convert image to base64 and avoid same-origin Policy - Stack Overflow

programmeradmin1浏览0评论

I'm trying to convert an image (link) to base64 to be able to store in the Browser side (IndexedDB), but i'm not able to do that, I have been looking for a solution for days and I didn't a solution to my problem.

In this awesome code I'm able to convert an image from internet to Base64, but the problem is that I can't do that for other images on internet because of the Same-origin policy.

How I would be able to avoid that problem or if you know any other solution to convert an image to Base64, that would be really helpful

function convertImgToBase64URL(url, callback, outputFormat){
    var img = new Image();
    img.crossOrigin = 'Anonymous';
    img.onload = function(){
        var canvas = document.createElement('CANVAS'),
        ctx = canvas.getContext('2d'), dataURL;
        canvas.height = img.height;
        canvas.width = img.width;
        ctx.drawImage(img, 0, 0);
        dataURL = canvas.toDataURL(outputFormat);
        callback(dataURL);
        canvas = null; 
    };
    img.src = url;
}
convertImgToBase64URL('.png', function(base64Img){
alert('it works');
      $('.output').find('img').attr('src', base64Img);  
   
});
<script src=".1.1/jquery.min.js"></script>
<div class="output"> <img> </div>

I'm trying to convert an image (link) to base64 to be able to store in the Browser side (IndexedDB), but i'm not able to do that, I have been looking for a solution for days and I didn't a solution to my problem.

In this awesome code I'm able to convert an image from internet to Base64, but the problem is that I can't do that for other images on internet because of the Same-origin policy.

How I would be able to avoid that problem or if you know any other solution to convert an image to Base64, that would be really helpful

function convertImgToBase64URL(url, callback, outputFormat){
    var img = new Image();
    img.crossOrigin = 'Anonymous';
    img.onload = function(){
        var canvas = document.createElement('CANVAS'),
        ctx = canvas.getContext('2d'), dataURL;
        canvas.height = img.height;
        canvas.width = img.width;
        ctx.drawImage(img, 0, 0);
        dataURL = canvas.toDataURL(outputFormat);
        callback(dataURL);
        canvas = null; 
    };
    img.src = url;
}
convertImgToBase64URL('http://upload.wikimedia/wikipedia/mons/4/4a/Logo_2013_Google.png', function(base64Img){
alert('it works');
      $('.output').find('img').attr('src', base64Img);  
   
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="output"> <img> </div>

Share Improve this question asked Apr 15, 2015 at 7:48 Stranger B.Stranger B. 9,37422 gold badges75 silver badges111 bronze badges 5
  • This code seems to convert images to base64 without any errors. What is the exact error / problem you are facing? – Anbarasan Commented Apr 15, 2015 at 8:01
  • You should to try another image from the web to understand the error, thanks for your ment anyway – Stranger B. Commented Apr 15, 2015 at 8:09
  • I tried to do so with a random image url from google search and also with an image from my local server, and there were no errors, that is why asked. – Anbarasan Commented Apr 15, 2015 at 8:10
  • Try this image http://www.pariskop.fr/wp-content/uploads/2014/12/psg-revons-plus-grand1.jpg – Stranger B. Commented Apr 15, 2015 at 8:22
  • i got the error. I don't think it will be possible to access the image either directly or via XMLHttpRequest without some sort of support from the server. May be this helps you understand why – Anbarasan Commented Apr 15, 2015 at 9:33
Add a ment  | 

3 Answers 3

Reset to default 5

While converting into base64 you can use a proxy URL (https://cors-anywhere.herokuapp./) before your image path to avoid cross-origin issue

var getDataUri = function (targetUrl, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function () {
        var reader = new FileReader();
        reader.onloadend = function () {
            callback(reader.result);
        };
        reader.readAsDataURL(xhr.response);
    };
    var proxyUrl = 'https://cors-anywhere.herokuapp./';
    xhr.open('GET', proxyUrl + targetUrl);
    xhr.responseType = 'blob';
    xhr.send();
};
getDataUri(path, function (base64) {
    // base64 availlable here
})

You need to download the image to a byte array first: Downloading binary data using XMLHttpRequest, without overrideMimeType

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.celticfc/images/doc/celticcrest.png', true);

xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
   if (this.status == 200) {
       var uInt8Array = new Uint8Array(this.response); // Note:not xhr.responseText

       for (var i = 0, len = uInt8Array.length; i < len; ++i) {
           uInt8Array[i] = this.response[i];
       }

       var byte3 = uInt8Array[4]; // byte at offset 4
   }
}

xhr.send();

Then you can use the byte array as follows: Javascript : How to display image from byte array using Javascript or Servlet?

<img id="ItemPreview" src="" />

document.getElementById("ItemPreview").src = "data:image/png;base64," + YourByteArray;

EDIT: I cannot try this ATM but you can alternatively save the file to the file system using the HTML5 FileSystem API: How to save a image to HTML5 filesystem with the url of image

window.requestFileSystem(window.PERSISTENT, 2*1024*1024, onFileSystemSuccess, fail);


function onFileSystemSuccess(fileSystem) {
    fs = fileSystem;
    console.log('File system initialized');

    saveAsset('http://www.example-site-with-cors./test.png');
}


function saveAsset(url, callback, failCallback) {
    var filename = url.substring(url.lastIndexOf('/')+1);

    // Set callback when not defined
    if (!callback) {
        callback = function(cached_url) {
            console.log('download ok: ' + cached_url);
        };
    }
    if (!failCallback) {
        failCallback = function() {
            console.log('download failed');
        };
    }

    // Set lookupTable if not defined
    if (!window.lookupTable)
        window.lookupTable = {};

    // BlobBuilder shim
    // var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    // xhr.responseType = 'blob';
    xhr.responseType = 'arraybuffer';

    xhr.addEventListener('load', function() {

        fs.root.getFile(filename, {create: true, exclusive: false}, function(fileEntry) {
            fileEntry.createWriter(function(writer) {

                writer.onwrite = function(e) {
                    // Save this file in the path to URL lookup table.
                    lookupTable[filename] = fileEntry.toURL();
                    callback(fileEntry.toURL());
                };

                writer.onerror = failCallback;

                // var bb = new BlobBuilder();
                var blob = new Blob([xhr.response], {type: ''});
                // bb.append(xhr.response);
                writer.write(blob);
                // writer.write(bb.getBlob());

            }, failCallback);
        }, failCallback);
    });

    xhr.addEventListener('error', failCallback);
    xhr.send();

    return filename;
}



function fail(evt) {
    console.log(evt.target.error.code);
}

for same origin policy you must add headers for server side from where you want your images

here is how to do this - http://enable-cors/server.html

for development purpose you can install 'CORS' extension in CHROME browser to allow cross origin request

hope this helps and solve your issue.

发布评论

评论列表(0)

  1. 暂无评论