从Web Worker发出AJAX请求是否可行?

24

我似乎不能在我的Web Worker中使用jQuery,我知道可以使用XMLHttpRequest来完成,但是当我读到这个答案时,那可能不是一个好选择。


我认为Ajax现在已经在所有常见的WebWorker实现中了。虽然添加完全使用Ajax2花费了一些时间,但现在它非常稳定。 - dandavis
ajax2?能解释一下吗? - qwertynl
XMLHttpRequest 2级:http://caniuse.com/xhr2 - dandavis
你能展示一个例子吗? - qwertynl
1
不,jQuery在Web Workers中不起作用。可以使用普通JS。您可能能够使用Zepto或一些Node.js DOM来工作,但这将比使用iframe更费力,而iframe可以运行jQuery、jsonp调用等。 - dandavis
3个回答

32

当然你可以在Web Worker内部使用AJAX,你只需要记住 AJAX 调用是异步的,因此你必须使用回调函数。

这是我在Web Worker中使用的ajax函数来访问服务端并进行AJAX请求:

var ajax = function(url, data, callback, type) {
  var data_array, data_string, idx, req, value;
  if (data == null) {
    data = {};
  }
  if (callback == null) {
    callback = function() {};
  }
  if (type == null) {
    //default to a GET request
    type = 'GET';
  }
  data_array = [];
  for (idx in data) {
    value = data[idx];
    data_array.push("" + idx + "=" + value);
  }
  data_string = data_array.join("&");
  req = new XMLHttpRequest();
  req.open(type, url, false);
  req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  req.onreadystatechange = function() {
    if (req.readyState === 4 && req.status === 200) {
      return callback(req.responseText);
    }
  };
  req.send(data_string);
  return req;
};

然后在您的worker内部,您可以这样做:

ajax(url, {'send': true, 'lemons': 'sour'}, function(data) {
   //do something with the data like:
   self.postMessage(data);
}, 'POST');

如果您通过 webworkers 发送 过多的 AJAX 请求,可能会遇到一些问题。您可能需要阅读此答案,了解其中的一些陷阱。


2
要发送JSON对象,您需要执行类似于req.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); data_string = JSON.stringify(data);的操作。 - Nathan Champion

2
如果要调用另一个域上使用 JSONP 的服务,您可以使用 importScripts 函数。例如:
// Helper function to make the server requests 
function MakeServerRequest() 
{ 
importScripts("http://SomeServer.com?jsonp=HandleRequest"); 
} 

// Callback function for the JSONP result 
function HandleRequest(objJSON) 
{ 
// Up to you what you do with the data received. In this case I pass 
// it back to the UI layer so that an alert can be displayed to prove 
// to me that the JSONP request worked. 
postMessage("Data returned from the server...FirstName: " + objJSON.FirstName + " LastName: " + objJSON.LastName); 
} 

// Trigger the server request for the JSONP data 
MakeServerRequest();

发现了这个很棒的技巧:http://cggallant.blogspot.com/2010/10/jsonp-overview-and-jsonp-in-html-5-web.html

2

只需使用来自Fetch API的JS函数fetch()。您还可以设置许多选项,如绕过CORS等(因此您可以使用Promises以更干净的方式实现与importScripts相同的行为)。

代码如下:

var _params = { "param1": value};

fetch("http://localhost/Service/example.asmx/Webmethod", {
    method: "POST",
    headers: {
        "Content-Type": "application/json; charset=utf-8"
    },
    body: JSON.stringify(_params )
}).then(function (response) {
    return response.json();
}).then(function (result) {
    console.log(result);
});

这个webservice的web.config看起来像这样:

<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Headers" value="Content-Type" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>
</configuration>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接