如何在用户脚本中处理多个 AJAX 结果?
我目前正在开发一个 Greasemonkey 脚本来翻译 Intranet 应用程序中的 <textarea>
字段,使用 Google Translation API.
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 :
请求实体太大
无论如何,我找到了一种将文本分割成片段的方法,并在单独的请求中发送它们.棘手的地方是,我应该如何替换原始文本区域中的这些片段,尤其是在正确的位置.
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}
...
但是现在在我的 XHR 的成功回调中,我必须用翻译后的文本替换占位符.问题是,我的 XHR 在 for
循环中,遍历包含原始文本片段的表,当请求完成时,循环很长,我不知道如何获取把翻译放在哪里.
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.
代码如下:
//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+"
Error : "+responseDetails.statusText);
}
}
});
}
PS : 我不能使用 jQuery 的 AJAX 方法,因为这是一个跨域请求,所以这里不能使用新的 $.when
功能(遗憾)
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)
推荐答案
更新:使用较新版本的 Greasemonkey 和 Tampermonkey,您现在可以通过 a context
Doc:
Update: With newer versions of Greasemonkey and Tampermonkey, you can now pass a context
Doc:
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+"
Error : "
+ responseDetails.statusText
);
}
}
} );
<小时>
对于其他/较旧的平台,要使用 i
的值,您需要 将其包装在 JavaScript 闭包. 一种方法是:
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+"
Error : "
+ responseDetails.statusText
);
}
}
} );
} ) (i);
相关文章