我们如何从背景中将大对象发送到CrossRider中的活动选项卡?

时间:2014-12-16 15:34:23

标签: javascript internet-explorer browser-extension crossrider

我们正在使用CrossRider为Internet Explorer开发扩展程序。我们的扩展程序具有向后台发送消息的代码,后台发送回复并调用回调函数。这可以在我的计算机上使用Internet Explorer 11,但在我的朋友Tom的计算机(也使用Internet Explorer 11)中,它不起作用 - 回调不会在他的计算机中调用。有什么问题,我们如何解决它在任何计算机上工作?以下是相关代码:

_base.js

alert("[ContentBase::getData] >>>>>"); // This happens in any computer.
var request = {command: 'get', webmail: thisObj.mContentType, param: param, type: type, contentType: contentType};
thisObj.sendRequest(request, function(response) {
    alert("[ContentBase::getData] received data >>>>>"); // This doesn't happen in Tom's computer.
    if (typeof(callback) === 'function') {
        callback(response);
    }
});

utils.js

this.sendRequest = function(request, callback) {
    if (typeof(callback) !== 'function') {
        callback = function(response) {};
    }

    switch (Sys.platform) {
        case 'crossrider':
            var message = {request: request, message_id: Math.floor((Math.random() * 900000000000000) + 100000000000000)};
            if (typeof thisObj.mCallbackMap === 'undefined') {
                thisObj.mCallbackMap = {};
                appAPI.message.addListener({channel: "message_from_background"}, function(message) {
                    if (typeof thisObj.mCallbackMap[message.message_id] === 'function') {
                        thisObj.mCallbackMap[message.message_id](message.response);
                        delete thisObj.mCallbackMap[message.message_id];
                    }
                });
            }

            (function(callback_inner) {
                thisObj.mCallbackMap[message.message_id] = function(response) {
                    if (typeof(callback_inner) === 'function') {
                        callback_inner(response);
                    }
                };
            })(callback);

            appAPI.message.toBackground(message, {channel: "message_to_background"});
            break;
    }
};

background.js

appAPI.message.addListener({channel: "message_to_background"}, function(params) {
    MsgHandler.handle(params.request, undefined, function(responseParams) {
        appAPI.message.toActiveTab({'message_id': params.message_id, 'response': responseParams}, {channel: "message_from_background"});
    });
});

msgHandler.js

this.handle = function(request, sender, callback_out) {
    function callback(response) {
        if (typeof(callback_out) === 'function') {
            callback_out(response);
        }
    }

    switch (request.command) {
        case "get":
            switch (request.type) {
                case "all":
                    var data = Controller.getData();
                    alert("[MsgHandler::handle] get / all, data.length = " + JSON.stringify(data).length + ", data = " + JSON.stringify(data)); // This happens in any computer.
                    callback({data: data});
                    break;
            }
            break;
    }
    return true;    //this return is needed for chrome in order to execute callbacks

};

Sys.platform始终等于' crossrider'。

更新:当JSON.stringify(data).length为5981字节时收到消息,但当它为10157字节时,活动标签未收到消息(appAPI.message.toActiveTab)。从后台发送的对象大小的限制是什么?我们如何将大对象发送到选项卡(最多100KB)?

我们的分机ID是43889.我使用的是Internet Explorer 11,但此扩展程序适用于所有版本的Internet Explorer。

顺便说一下,来自后台的其他来电工作,只有这个特定的电话不起作用。我们在Tom的计算机上多次尝试过,但它永远无法运行。

编辑:我创建了一个具有相同问题的简单扩展,扩展ID为67708.以下是简单扩展的代码:

extension.js

appAPI.ready(function($) {
    alert("appAPI.platform = " + appAPI.platform);
    if (appAPI.platform === 'IE') {

        appAPI.message.addListener({channel: "message_from_background"}, function(message) {
            alert("message_from_background received, message_id = " + message.message_id + ", message.length = " + JSON.stringify(message).length + ", message = " + JSON.stringify(message));
        });

        appAPI.message.toBackground({}, {channel: "init_background"});
    }
});

background.js

appAPI.ready(function($) {
    alert("appAPI.platform = " + appAPI.platform);
    if (appAPI.platform === 'IE') {
        var ready = false;
        appAPI.message.addListener({channel: "init_background"}, function(params) {
            if (ready === false) {
                alert('init_background, ready = ' + ready);
                ready = true;

                var message_id = 9999;
                var responseParams = {'a': 1, 'b': 2, 'c': 3};
                alert('sending message to active tab, message_id = ' + message_id + ', responseParams.length = ' + JSON.stringify(responseParams).length);
                appAPI.message.toActiveTab({'message_id': message_id, 'response': responseParams}, {channel: "message_from_background"});

                var message_id = 9998;
                var responseParams = {
                    // a big object
                };
                alert('sending message to active tab, message_id = ' + message_id + ', responseParams.length = ' + JSON.stringify(responseParams).length);
                appAPI.message.toActiveTab({'message_id': message_id, 'response': responseParams}, {channel: "message_from_background"});

                alert(appAPI.platform);
            }
        });
    }
});

JSON.stringify(responseParams).length为19个字节时,活动选项卡会收到该消息,但当它为10576字节时,则不会收到该消息。

2 个答案:

答案 0 :(得分:2)

@Uri感谢更新的问题。

根据新信息,我会提请您注意有关Internet Explorer限制的文档(appAP.message)中的说明:

  

消息在发送之前会转换为JSON字符串。由于一个   Internet Explorer中的限制,JSON字符串的最大长度   是8000字节(8Kb)。

您可以通过将数据保存在本地数据库中并向活动选项卡发送短消息以触发其读取数据来解决此问题。以下是该流程的简化示例:

<强> background.js

appAPI.ready(function($) {
  appAPI.db.async.set(
    'my-data',
    myData,
    appAPI.time.minutesFromNow(1),
    function() {
      appAPI.message.toActiveTab({type: 'get-data'});
    }
  );
});

<强> extension.js

appAPI.ready(function($) {
  appAPI.message.addListener(function(msg) {
    if (msg.type === 'get-data') {
      appAPI.db.async.get('my-data', function(data) {
        // do something with data
      });
    }
  });
});

[披露:我是Crossrider员工]

答案 1 :(得分:1)

好的,因为消息中对象的大小限制为8000字节,所以我将对象划分为大小最多为5000字节的数据包。这是我的扩展代码:

<强> utils.js

this.sendRequest = function(request, callback) {
    if (typeof(callback) !== 'function') {
        callback = function(response) {};
    }

    switch (Sys.platform) {
        case 'crossrider':
            var message = {request: request, message_id: Math.floor((Math.random() * 900000000000000) + 100000000000000)};
            if (typeof thisObj.mCallbackMap === 'undefined') {
                thisObj.mCallbackMap = {};
                thisObj.mResponseObject = {};
                appAPI.message.addListener({channel: "message_from_background"}, function(message) {
                    alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", checking message...");
                    if ((typeof(message) === 'object') && (!(message === null)) && (typeof(message['divided_object_length']) === 'number')) {
                        if (typeof thisObj.mResponseObject[message.message_id] === 'undefined') {
                            thisObj.mResponseObject[message.message_id] = {}
                        }
                        var limit = message['divided_object_length'];
                        var packet_id = message['packet_id'];
                        var packet = message['packet'];
                        alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", limit = " + limit + ", packet_id = " + packet_id + "...");
                        thisObj.mResponseObject[message.message_id]['packet_' + packet_id] = packet;
                        var message_is_ready = true;
                        for (var packet_id = 0; packet_id < limit; packet_id++) {
                            if (typeof thisObj.mResponseObject[message.message_id]['packet_' + packet_id] === 'undefined') {
                                var message_is_ready = false;
                            }
                        }
                        if (message_is_ready) {
                            delete message['divided_object_length'];
                            delete message['packet_id'];
                            delete message['packet'];
                            var s = '';
                            for (var packet_id = 0; packet_id < limit; packet_id++) {
                                s += thisObj.mResponseObject[message.message_id]['packet_' + packet_id];
                            }
                            message.response = JSON.parse(s);
                            delete thisObj.mResponseObject[message.message_id];
                        }
                    } else {
                        var message_is_ready = true;
                    }
                    alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", message_is_ready = " + message_is_ready + "...");
                    if (message_is_ready) {
                        if (typeof thisObj.mCallbackMap[message.message_id] === 'function') {
                            alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", calling function...");
                            thisObj.mCallbackMap[message.message_id](message.response);
                            delete thisObj.mCallbackMap[message.message_id];
                        }
                    }
                });
            }

            (function(callback_inner) {
                thisObj.mCallbackMap[message.message_id] = function(response) {
                    alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", checking inner function...");
                    if (typeof(callback_inner) === 'function') {
                        alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", calling inner function...");
                        callback_inner(response);
                    }
                };
            })(callback);

            appAPI.message.toBackground(message, {channel: "message_to_background"});
            break;
    }
};

<强> background.js

appAPI.message.addListener({channel: "message_to_background"}, function(params) {
    alert("background.js :: message received, params = " + JSON.stringify(params));

    MsgHandler.handle(params.request, undefined, function(responseParams) {
        alert("background.js :: message received callback, message_id = " + params.message_id + ", sending response.");

        var s = JSON.stringify(responseParams);
        if ((typeof(s) === "string") && (s.length > 5000)) {
            var limit = Math.floor((s.length - 1) / 5000) + 1;
            alert("background.js :: message received callback, message_id = " + params.message_id + ", sending response, s.length = " + s.length + ", limit = " + limit + ".");
            for (var packet_id = 0; packet_id < limit; packet_id++) {
                var message = {};
                message['divided_object_length'] = limit;
                message['message_id'] = params.message_id;
                message['packet_id'] = packet_id;
                message['packet'] = s.substr(packet_id * 5000, 5000);
                appAPI.message.toActiveTab(message, {channel: "message_from_background"});
            }
        } else {
            appAPI.message.toActiveTab({'message_id': params.message_id, 'response': responseParams}, {channel: "message_from_background"});
        }
    });
});

其余代码与我的问题相同(警报仅用于调试,我们在生产中将其删除)。