如何处理用户脚本中的多个 AJAX 结果?

发布于 2024-10-20 03:59:34 字数 1599 浏览 2 评论 0原文

我目前正在开发一个 Greasemonkey 脚本,以使用 Google Translation API 翻译 Intranet 应用程序中的

但有些文本太大,仅凭一个请求就无法翻译。我在尝试时收到此错误:

请求实体太大

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

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

{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 功能不能在这里使用(遗憾的是)

I'm currently developing a Greasemonkey script to translate <textarea> fields in an Intranet app, using Google Translation API.

But some texts are way too large to be translated with only one request. I get this error when trying :

Request entity too large

Anyway, I found a way to cut the texts in fragments, and send them in separate requests. Where it gets tricky, is how I should replace those fragments in their original textareas, and especially at the right place.

After trying several methods without any success, I inserted placeholders in the textarea, corresponding to the fragments of text that have to be translated :

{1}
{2}
...

But now in the success callback of my XHR, I have to replace the placeholder with the translated text. The thing is, my XHR is inside a for loop, iterating over my table containing the fragments of original text, and when the requests finish, the loop is long finished and I don't know how to get where to put the translation.

Here's the code :

//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(/"/g,"\"").replace(/'/g,"\"").replace(/>/g,">");
            textarea.text(textarea.text().replace("{"+i+"}",translated_text[i]));
        }
        else
        {
            alert('Request Failed : '+responseDetails.status+"\nError : "+responseDetails.statusText);
        }
    }
});
}

PS : I cannot use jQuery's AJAX methods, because this is a Cross Domain request, so the new $.when functionality cannot be used here (sadly)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怀念你的温柔 2024-10-27 03:59:34

更新:使用较新版本的 Greasemonkey 和 Tampermonkey,您现在可以传递 a  ;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 (/"/g,"\"")
                                      .replace (/'/g,"\"").replace (/>/g,">")
                                      ;
                   textarea.text (textarea.text ().replace ("{"+i+"}",translated_text[i]) );
                }
                else {
                   alert (
                      'Request Failed : '+responseDetails.status+"\nError : "
                      + responseDetails.statusText
                   );
                }
             }
} );

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

( 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 (/"/g,"\"")
                                         .replace (/'/g,"\"").replace (/>/g,">")
                                         ;
                      textarea.text (textarea.text ().replace ("{"+i+"}",translated_text[i]) );
                   }
                   else {
                      alert (
                         'Request Failed : '+responseDetails.status+"\nError : "
                         + responseDetails.statusText
                      );
                   }
                }
   } );
} ) (i);

Update: With newer versions of Greasemonkey and Tampermonkey, you can now pass 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 (/"/g,"\"")
                                      .replace (/'/g,"\"").replace (/>/g,">")
                                      ;
                   textarea.text (textarea.text ().replace ("{"+i+"}",translated_text[i]) );
                }
                else {
                   alert (
                      'Request Failed : '+responseDetails.status+"\nError : "
                      + responseDetails.statusText
                   );
                }
             }
} );

For other/older platforms, to use the value of i, you need to wrap it in a JavaScript closure. One way to do do that is:

( 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 (/"/g,"\"")
                                         .replace (/'/g,"\"").replace (/>/g,">")
                                         ;
                      textarea.text (textarea.text ().replace ("{"+i+"}",translated_text[i]) );
                   }
                   else {
                      alert (
                         'Request Failed : '+responseDetails.status+"\nError : "
                         + responseDetails.statusText
                      );
                   }
                }
   } );
} ) (i);
清旖 2024-10-27 03:59:34

据我了解,您可以使用 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 并在返回时连接文本,将其分配给具有外部作用域的变量。

As far as I understand it you can use jQuery to do cross domain requests like this...

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;
      }
    });

The 'crossDomain: true' property is new to jQuery 1.5. Also, I think you could make use of success and complete and just concatenate the text as it returns, assigning it to a variable with outer scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文