What is analog of URL.createObjectURL for Service Worker

Viewed 609

With manifest v2, I used URL.createObjectURL in order to return file from background to content. How do this with manifest v3 and Service Worker? I know about XMLHttpRequest to fetch. But what analog URL.createObjectURL?

// background.js
function onContentMessage(message, sender, sendResponse) {
    if (message.action == 'requestFileGET') {
        requestFileGET(message.url, (url) => sendResponse(url));
    }
    return true;
}

function requestFileGET(url, callback) {
    let request = new XMLHttpRequest();
    request.responseType = 'blob';
    request.onreadystatechange = function () {
        if (request.readyState == 4) {
            let url = URL.createObjectURL(request.response);
            callback(url);
        }
    };
    request.open('GET', url);
    request.send();
}
// content.js
backgroundFileGET(urlCover, (cover) => {
    let url = `${HANDLER_UPLOADPIC}?kind=${kind}&sign=${sign}`;
    let formData = new FormData();
    formData.append('file', cover);
    requestFilePOST(url, formData, callback);
});

function backgroundFileGET(url, callback) {
    backgroundRequest('requestFileGET', url, (backgroungdUrl) => {
        requestFileGET(backgroungdUrl, (file) => callback(file));
    });
}

function backgroundRequest(action, url, callback) {
    chrome.runtime.sendMessage({ action: action, url: url }, (response) => callback(response));
}
1 Answers

My Solution Store the data with a ID and open a new tab with a page like download.html#ID

let videoId = '#' + new Date().valueOf();
self.DownloadedVideoData[videoId] = { data: data, filename: 
filename, mimetype:mimetype, segment:segment, action:'download' };
chrome.tabs.create({ url: "video.html" + videoId, active: false });

Inside the Page register a function to onload and your downloading Code

chrome.runtime.sendMessage({
    action: 'GetVideoDataByID',
    VideoID: self.VideoID,
}, function (videoData) {
    if (videoData.action == 'download') self.DownloadVideo(videoData);
);

self.DownloadVideo = function (request) {
    let blob = new Blob(request.data, { type: request.mimetype }),
    downloadId;

    chrome.downloads.onChanged.addListener(function (dl) {
        if (dl.id === downloadId && dl.state && dl.state.current == 
         'complete') {
            window.close();
        }
    });

    chrome.downloads.download({
        url: URL.createObjectURL(blob),
        filename: request.filename
    }, function (id) {
        downloadId = id;
        window.close();
    });
}

Now you need only a Listener in your Backround Worker like that

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
     switch (request.action) {
        case 'GetVideoDataByID':
            sendResponse(self.GetVideoDataByID(request.VideoID));
            break;
        default:
            break;
     }
}
Related