1

我在使用调用getResponseHeaderGreasemonkey 脚本时获得的值时遇到问题。

首先,我声明了以下全局变量:

size = 0;
maxS = 153600; // Max. size (bytes).

一旦网站完全加载,我的 main 函数就会被调用,并在其中获取某个 div 中的所有图像(此处未显示,因为它不相关):

function main() {
    ...
    var imgs = posts[i].getElementsByTagName('img');
    for (var j = 0; j < imgs.length; ++j) {
        getFileSize(imgs[j].src, responseHandler);
        if (size > maxS)
            // Do something
    }
    ...
}

这就是getFileSize工作原理:

var getFileSize = function(address, responseHandler) {
    var req = new XMLHttpRequest();
    req.open('head', address, true);
    req.onreadystatechange = responseHandler;
    req.send(null);
};

var responseHandler = function(resp) {
    if (this.readyState == 1)
    this.abort();
    size = this.getResponseHeader("Content-length");
};

问题是即使我在句子之后检查size的值

size = this.getResponseHeader("Content-length");

该值是我期望的值,在 main 函数中,当它到达这部分代码时,它的值仍然为 0:

if (size > maxS)
    // Do something

我试图通过检查我在这个网站上找到的其他一些问题来找出答案,我这与同步有关,但我真的不知道如何解决这个问题。

4

1 回答 1

2

图像都在完全相同的服务器上,对吧? XMLHttpRequest()不会进行跨域请求(无论如何,没有一些不适用于 Greasemonkey 上下文的新箍)。

该代码存在一些问题:

  1. 它期望大小同步设置,但XMLHttpRequest()异步调用。
  2. 它中止请求!而且太快了。没有充分的理由中止HEAD请求。
  3. 它以一种模糊的方式使用“幻数”。如果可用,请使用适当的枚举常量。EGthis.readyState == 1不好。 this.readyState == this.OPENED更好。

对于同步操作,更改getFileSize(). 像这样称呼它:

getFileSize (imgs[j].src);

像这样定义它:

function getFileSize (address) {
    var request = new XMLHttpRequest();  
    request.open ('HEAD', address, false);  //-- false = Synchronous
    request.send (null);  

    size        = -666; // Error, or AJAX fail.
    if (request.status === 200) {  
        size    = request.getResponseHeader ("Content-length");
    }  
}



笔记:

  1. 出于性能和用户友好的原因,最好重构使用异步 AJAX 的方法。但这是另一个问题,不太直观。
  2. 如果图像是跨域的,您将需要使用GM_xmlhttpRequest()-- 它的操作略有不同,并且对于同步 AJAX 无法正常工作(我上次检查过 -- 几个月前)。
于 2012-05-14T10:07:25.107 回答