【问题标题】:How can I handle multiple AJAX results in a userscript?如何在用户脚本中处理多个 AJAX 结果?
【发布时间】:2011-07-08 16:34:03
【问题描述】:

我目前正在开发一个 Greasemonkey 脚本来翻译 Intranet 应用程序中的 <textarea> 字段,使用 Google Translation API。

但有些文本太大而无法仅通过一个请求进行翻译。尝试时出现此错误:

请求实体太大

不管怎样,我找到了一种将文本分割成片段的方法,并在单独的请求中发送它们。棘手的地方是,我应该如何替换原始文本区域中的这些片段,尤其是在正确的位置。

在尝试了几种方法都没有成功后,我在文本区域中插入了占位符,对应于需要翻译的文本片段:

{1}
{2}
...

但是现在在我的 XHR 的成功回调中,我必须用翻译后的文本替换占位符。问题是,我的 XHR 在 for 循环中,遍历包含原始文本片段的表,当请求完成时,循环很长,我不知道如何将翻译放在哪里.

代码如下:

//Array text[] contains the fragments of original text
var translated_text = [];
var l = text.length;
for(var i = 0; i < l; i++)
{
var fullurl = apiurl+encodeURIComponent(text[i]);
GM_xmlhttpRequest({
    method: 'GET',
    url: fullurl,
    headers:
    {
        'User-agent': 'Mozilla/5.0 (compatible) Greasemonkey',
        'Accept': 'application/atom+xml,application/xml,text/xml',
    },
    onload: function(responseDetails)
    {
        var destination = "{"+i+"}";
        if(responseDetails.status == 200)
        {
            var data = $.parseJSON(responseDetails.responseText);
            translated_text[i] = data.responseData.translatedText.replace(/&quot;/g,"\"").replace(/&#39;/g,"\"").replace(/&gt;/g,">");
            textarea.text(textarea.text().replace("{"+i+"}",translated_text[i]));
        }
        else
        {
            alert('Request Failed : '+responseDetails.status+"\nError : "+responseDetails.statusText);
        }
    }
});
}

PS : 我不能使用 jQuery 的 AJAX 方法,因为这是一个跨域请求,所以这里不能使用新的 $.when 功能(遗憾)

【问题讨论】:

    标签: javascript loops xmlhttprequest greasemonkey tampermonkey


    【解决方案1】:

    据我了解,您可以使用 jQuery 进行这样的跨域请求...

    function pass_ajax(url,text_to_translate){
        $.ajax({
          type: 'GET',
          url: url,
          crossDomain: true,
          data: text_to_translate,
          dataType: 'json',
          success: function(data){
            req = data; //here you can sanitize the data before concatenating
          },
          complete: function(xhr,textStatus){
            translated_text += req;
          }
        });
    

    'crossDomain: true' 属性是 jQuery 1.5 的新特性。另外,我认为您可以利用 success 和 complete 并在返回文本时将其连接起来,将其分配给具有外部范围的变量。

    【讨论】:

    • 它与 jQuery 1.5.1 完美配合,除了 ajax/跨域部分
    【解决方案2】:

    更新:使用较新版本的 Greasemonkey 和 Tampermonkey,您现在可以通过contextDoc

    GM_xmlhttpRequest ( {
       method:   'GET',
       url:      fullurl,
       context:  i,
       headers:  {
                   'User-agent': 'Mozilla/5.0 (compatible) Greasemonkey',
                   'Accept': 'application/atom+xml,application/xml,text/xml',
                 },
       onload:   function (responseDetails) {
                    var destination = "{" + responseDetails.context + "}";  // context is `i`
                    if (responseDetails.status == 200) {
                       var data           = $.parseJSON (responseDetails.responseText);
                       translated_text[i] = data.responseData.translatedText.replace (/&quot;/g,"\"")
                                          .replace (/&#39;/g,"\"").replace (/&gt;/g,">")
                                          ;
                       textarea.text (textarea.text ().replace ("{"+i+"}",translated_text[i]) );
                    }
                    else {
                       alert (
                          'Request Failed : '+responseDetails.status+"\nError : "
                          + responseDetails.statusText
                       );
                    }
                 }
    } );
    

    对于其他/较旧的平台,要使用i 的值,您需要将其包装在JavaScript closure 中。 一种方法是:

    ( function (i)  {
       GM_xmlhttpRequest ( {
          method:   'GET',
          url:      fullurl,
          headers:  {
                      'User-agent': 'Mozilla/5.0 (compatible) Greasemonkey',
                      'Accept': 'application/atom+xml,application/xml,text/xml',
                    },
          onload:   function (responseDetails) {
                       var destination = "{"+i+"}";
                       if (responseDetails.status == 200) {
                          var data           = $.parseJSON (responseDetails.responseText);
                          translated_text[i] = data.responseData.translatedText.replace (/&quot;/g,"\"")
                                             .replace (/&#39;/g,"\"").replace (/&gt;/g,">")
                                             ;
                          textarea.text (textarea.text ().replace ("{"+i+"}",translated_text[i]) );
                       }
                       else {
                          alert (
                             'Request Failed : '+responseDetails.status+"\nError : "
                             + responseDetails.statusText
                          );
                       }
                    }
       } );
    } ) (i);
    

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-14
      • 2018-01-30
      • 2015-12-07
      相关资源
      最近更新 更多