XMLHttpRequest到Web服务不在web worker中工作 [英] XMLHttpRequest to webservice not working in web worker

查看:226
本文介绍了XMLHttpRequest到Web服务不在web worker中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果从主javascript调用,下面的代码运行完美,但它不会在web worker中运行。

  function getSpecData(detailLvl,startWeek,endWeek,mkt){
var params = {detailLvl:detailLvl,startWeek:startWeek,endWeek:endWeek,mkt:mkt};
var xhr;
var url =WebServices / wsSProgress.asmx / GetSpecProgressTable;
try {
xhr = new XMLHttpRequest();
xhr.open('POST',url,false);
xhr.setRequestHeader('Content-Type','application / json');
xhr.onreadystatechange = function(){
if(xhr.readyState == 4&& xhr.status == 200){
var result = JSON.parse(xhr.responseText );
$('#specProgTbl')。html(result.d);
}
};
xhr.send(JSON.stringify(params));
} catch(e){
alert('XMLHttpRequest中出现错误:'+ xhr.statusText +'ReadyState:'+ xhr.readyState +'Status:'+ xhr.status);
}
}


网络工作者代码的唯一区别是它使用postMessage返回结果:

 < script id =workertype =javascript /工人> 

self.onmessage = function(e){
var data = e.data;
//self.postMessage(data.mkt ++ data.detailLvl ++ data.refreshMin ++ data.isRotate ++ data.weekNum);

var startWeek = data.weekNum-3;
var endWeek = data.weekNum;
self.postMessage(getSpecData(1,startWeek,endWeek,data.mkt));

};
函数getSpecData(detailLvl,startWeek,endWeek,mkt){
self.postMessage('DetailLvl'+ detailLvl +'Start'+ startWeek +'End'+ endWeek +'Mkt'+ mkt);
var params = {detailLvl:detailLvl,startWeek:startWeek,endWeek:endWeek,mkt:mkt};
var xhr;
var url =WebServices / wsSpecProgress.asmx / GetSpecProgressTable;
try {
xhr = new XMLHttpRequest();
xhr.open('POST',url,false);
xhr.setRequestHeader('Content-Type','application / json');
xhr.onreadystatechange = function(){
if(xhr.readyState == 4&& xhr.status == 200){
var result = JSON.parse(xhr.responseText );
self.postMessage(result.d);
}
};
xhr.send(JSON.stringify(params));
} catch(e){
self.postMessage('XMLHttpRequest中出现错误:'+ xhr.statusText +'ReadyState:'+ xhr.readyState +'Status:'+ xhr.status);
}
}

< / script>


启动工人的主要javascript:

  $(函数initialize(){
$('#options')。hide();
$([id $ = 'btnViewOpt'])。val(查看选项);
var mkt = $([id $ ='lstMkt']:selected)。text();
var detailLvl = $ ([id $ ='lstDetailLvl']:selected)。val();
var refreshMin = $([id $ ='lstRefresh']:selected)。val();
var isRotate = $([id $ ='chkRotate'])。is(:checked);

var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
window.URL = window.URL || window.webkitURL;
if(BlobBuilder){
var bb = new BlobBuilder();
bb.append(document.querySelector( '#worker')。textContent);
wUrl = window.URL.createObjectURL(bb.getBlob());
worker = new Worker(wUrl);
alert(Web worker star ted);
worker.addEventListener('message',dispMsg,false);
worker.addEventListener('error',onError,false);
worker.postMessage({'mkt':mkt,'detailLvl':detailLvl,'refreshMin':refreshMin,'isRotate':isRotate,'weekNum':getCurrentWeekNumber()}); //启动工作人员
}
else
alert(您的浏览器不支持网络工作者);
});

函数onError(e){
alert('WebWorker中的错误:行'+ e.lineno +'in'+ e.filename +':'+ e.message);
}
函数dispMsg(e){
alert(来自工人的消息:+ e.data);
$('#specProgTbl')。html(e.data);

}



网络工作者启动和params是正确的但 result.d未定义。 catch没有statusText,只有 readyState = 0 status = 0

这是什么巫术?





更新

xhr.responseText 如果从主Javascript调用:

  {d: \\\PAS\\\\\\\\\\\\NoSpec W25\\\\\\ \ u003ctd align = \\\'center\\\' class = \\\'percSame\\\' height = \ u002710 \ u0027 \ u003e \ u003cdiv style = \\\ 0000background-image:l inear-gradient(左,rgba(8,68,250,1)18%,rgba(240,241,250,1 ...............} 


解决方案

好的,我真的很傻。我之所以得到

  DOMException:INVALID_STATE_ERR 


是因为根据 W3文档<如果 xhr.readyState 的值无效,则 xhr.status 属性会抛出异常:

 检索时的异常
DOMException如果在readyState具有不适当的值时访问此属性,则应该引发异常INVALID_STATE_ERR异常。



我的 xhr.readyState 无效因为我没有指定我正在调用的web服务的完整路径。需要完整的Web服务路径,因为webworker在单独的 Blob文件中即时创建。

无论如何,下面是具有工作webservice调用脚本的webwoker代码:

 < script id =workertype =javascript / worker> 

self.onmessage = function(e){
var param = e.data;
var url =http:// localhost:54071 / WebServices / wsSProgress.asmx / GetSpecProgressTable;
var data = getSpecData(param.detailLvl,param.startWeek,param.endWeek,param.mkt,url)
self.postMessage(data);
};
函数getSpecData(detailLvl,startWeek,endWeek,mkt,url){
var params = {detailLvl:detailLvl,startWeek:startWeek,endWeek:endWeek,mkt:mkt} ;
var xhr;
try {
xhr = new XMLHttpRequest();
xhr.open('POST',url,false);
xhr.setRequestHeader('Content-Type','application / json');
xhr.onreadystatechange = function(){
if(xhr.readyState == 4&& xhr.status == 200){
var result = JSON.parse(xhr.responseText );
self.postMessage(result.d);
}
};
xhr.send(JSON.stringify(params));
} catch(e){
self.postMessage('XMLHttpRequest中出现错误:'+ xhr.statusText +'ReadyState:'+ xhr.readyState +'状态:'+ xhr.status +'E :'+ e +'Msg:'+ e.message);
}
}
< / script>


The code below runs perfectly if called from main javascript, but it does not run in the web worker.

  function getSpecData(detailLvl, startWeek, endWeek, mkt) {
        var params = { "detailLvl": detailLvl, "startWeek": startWeek, "endWeek": endWeek, "mkt": mkt };
        var xhr;
        var url = "WebServices/wsSProgress.asmx/GetSpecProgressTable";
        try {
            xhr = new XMLHttpRequest();
            xhr.open('POST', url, false);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = JSON.parse(xhr.responseText);
                    $('#specProgTbl').html(result.d);
                }
            };
            xhr.send(JSON.stringify(params));
        } catch (e) {
            alert('Error occured in XMLHttpRequest: ' + xhr.statusText + '  ReadyState: ' + xhr.readyState + ' Status:' + xhr.status);
        }
    }


The only difference in the web worker code is that it uses postMessage to return the result:

<script id="worker" type="javascript/worker">

    self.onmessage = function (e) {
        var data = e.data;
        //self.postMessage(data.mkt + " " + data.detailLvl + " " + data.refreshMin + " " + data.isRotate +" "+data.weekNum);

        var startWeek=data.weekNum-3;
        var endWeek=data.weekNum;
        self.postMessage(getSpecData(1,startWeek,endWeek,data.mkt));

    }; 
    function getSpecData(detailLvl, startWeek, endWeek, mkt) {
        self.postMessage('DetailLvl '+detailLvl+' Start '+startWeek+' End '+endWeek+' Mkt '+mkt); 
        var params = { "detailLvl": detailLvl, "startWeek": startWeek, "endWeek": endWeek, "mkt": mkt };
        var xhr;
        var url = "WebServices/wsSpecProgress.asmx/GetSpecProgressTable";
        try {
            xhr = new XMLHttpRequest();
            xhr.open('POST', url, false);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = JSON.parse(xhr.responseText);
                    self.postMessage(result.d);
                }
            }; 
            xhr.send(JSON.stringify(params));
        } catch (e) {
            self.postMessage('Error occured in XMLHttpRequest: ' + xhr.statusText + '  ReadyState: ' + xhr.readyState + ' Status:' + xhr.status);
        }
    }

</script>


The main javascript starting the worker:

  $(function initialize() {
        $('#options').hide();
        $("[id$='btnViewOpt']").val("View Options");
        var mkt = $("[id$='lstMkt'] :selected").text();
        var detailLvl = $("[id$='lstDetailLvl'] :selected").val();
        var refreshMin = $("[id$='lstRefresh'] :selected").val();
        var isRotate = $("[id$='chkRotate']").is(":checked");

        var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
        window.URL = window.URL || window.webkitURL;
        if (BlobBuilder) {
            var bb = new BlobBuilder();
            bb.append(document.querySelector('#worker').textContent);
            wUrl = window.URL.createObjectURL(bb.getBlob());
            worker = new Worker(wUrl);
            alert("Web worker started");
            worker.addEventListener('message', dispMsg, false);
            worker.addEventListener('error', onError, false);
            worker.postMessage({ 'mkt': mkt, 'detailLvl': detailLvl, 'refreshMin': refreshMin, 'isRotate': isRotate, 'weekNum': getCurrentWeekNumber() }); // Start the worker.
        }
        else
            alert("Your browser does not support web workers");
 });

  function onError(e) {
        alert('ERROR in WebWorker: Line ' + e.lineno + ' in ' + e.filename + ': ' + e.message);
    }
    function dispMsg(e) {
        alert("Message from worker: " + e.data);
        $('#specProgTbl').html(e.data);

    }



The web worker starts and the params are correct but result.d is undefined. The catch has no statusText and just readyState=0 and status=0.

What sorcery is this???



UPDATE

xhr.responseText if called from main Javascript is:

   {"d":"\u003ctable border=\u00271px\u0027 cellpadding=\u00275\u0027 cellspacing=\u00270\u0027\u003e\u003ctr height=\u002710\u0027 \u003e\u003cth height=\u002710\u0027 colspan=\u002712\u0027\u003ePAS\u003c/th\u003e\u003c/tr\u003e\u003ctr height=\u002710\u0027 \u003e\u003ctd align=\u0027center\u0027 width=\u0027200\u0027\u003eManufacturer\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027150\u0027\u003eMake\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eNoSpec W22\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eComplete% W22\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eNoSpec W23\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eComplete% W23\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eNoSpec W24\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eComplete% W24\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eNoSpec W25\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eComplete% W25\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eNoSpec W26\u003c/td\u003e\u003ctd align=\u0027center\u0027 width=\u0027100\u0027\u003eComplete% W26\u003c/td\u003e\u003c/tr\u003e\u003ctr height=\u002710\u0027 \u003e\u003ctd align=\u0027left\u0027  class=\u0027default\u0027  height=\u002710\u0027 \u003eAAD\u003c/td\u003e\u003ctd align=\u0027left\u0027  class=\u0027default\u0027  height=\u002710\u0027 \u003eCHERY\u003c/td\u003e\u003ctd align=\u0027left\u0027 class=\u0027noSpecSame\u0027  height=\u002710px\u0027 \u003e0\u003c/td\u003e\u003ctd align=\u0027center\u0027  class=\u0027percSame\u0027  height=\u002710\u0027 \u003e\u003cdiv style=\u0027background-image: linear-gradient(left , rgba(8,68,250,1) 18%, rgba(240,241,250,1) 92%, rgba(240,241,250,0) 8%);background-image: -o-linear-gradient(left , rgba(8,68,250,1) 18%, rgba(240,241,250,1) 92%, rgba(240,241,250,0) 8%);background-image: -moz-linear-gradient(left , rgba(8,68,250,1) 18%, rgba(240,241,250,1) 92%, rgba(240,241,250,0) 8%);background-image: -webkit-linear-gradient(left , rgba(8,68,250,1) 18%, rgba(240,241,250,1) 92%, rgba(240,241,250,0) 8%);background-image: -ms-linear-gradient(left , rgba(8,68,250,1) 18%, rgba(169,199,245,1) 92%, rgba(240,241,250,0) 8%);background-image: -webkit-gradient(linear,left bottom,right bottom,color-stop(0.18, rgba(8,68,250,1)),color-stop(0.92, rgba(240,241,250,1)),color-stop(1, rgba(240,241,250,0)));\u0027\u003e92\u003c/div\u003e\u003c/td\u003e\u003ctd align=\u0027left\u0027 class=\u0027noSpecSame\u0027  height=\u002710\u0027 \u003e0\u003c/td\u003e\u003ctd align=\u0027center\u0027  class=\u0027percSame\u0027 height=\u002710\u0027 \u003e\u003cdiv style=\u0027background-image: linear-gradient(left , rgba(8,68,250,1) 18%, rgba(240,241,250,1..............."}

Ok I was really stupid here. The reason why I was getting the

 DOMException: INVALID_STATE_ERR


was because according to
W3 documentation the xhr.status attribute throws an exception if xhr.readyState has an invalid value:

    Exceptions on retrieval
    DOMException  INVALID_STATE_ERR exception SHOULD be raised if this attribute is accessed when readyState has an inappropriate value. 


I had an invalid xhr.readyState since I did not specify a full path to the webservice I am calling. The full path to the webservice is needed because the webworker runs in the separate Blob file created "on the fly".

Anyway, below is the webwoker code with working webservice call script:

<script id="worker" type="javascript/worker">

    self.onmessage = function (e) {
        var param = e.data;
        var url="http://localhost:54071/WebServices/wsSProgress.asmx/GetSpecProgressTable";
        var data=getSpecData(param.detailLvl,param.startWeek,param.endWeek,param.mkt,url)
        self.postMessage(data);
    }; 
    function getSpecData(detailLvl, startWeek, endWeek, mkt, url) {
        var params = { "detailLvl": detailLvl, "startWeek": startWeek, "endWeek": endWeek, "mkt": mkt };
        var xhr;
        try {
            xhr = new XMLHttpRequest();
            xhr.open('POST', url, false);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = JSON.parse(xhr.responseText);
                    self.postMessage(result.d);
                }
            }; 
            xhr.send(JSON.stringify(params));
        } catch (e) {
            self.postMessage('Error occured in XMLHttpRequest: ' + xhr.statusText + '  ReadyState: ' + xhr.readyState + ' Status:' + xhr.status + ' E: ' +e+' Msg:'+e.message);
        }
    }
    </script>

这篇关于XMLHttpRequest到Web服务不在web worker中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆
Manufacturer\\\\\\Make\\ \\ u003c / td \ u003e \ u003ctd align = \\\'center\\\' width = \\\'100 \ u0027 \\\>NoSpec W22 \\\Complete%W25\\\\\\NoSpec W26\\\\\\AAD\\\\\\CHERY \ u003c / td \ u003e \ u003ctd align = \\\'left\\\' class = \\\'noSpecSame\\\' height = \ u002710px\\\' \\\>0\\\\\\\\\

0\\\