为什么我的Chrome扩展程序不能自动更新?

9
我制作了一个非常基本的Chrome扩展,并设置了一个简单的node.js服务器来测试自动更新功能。服务器托管.crx文件,因此我可以通过访问“http://localhost:3000/clients/chrome/extension.crx”轻松安装扩展。但是,当我转到“工具”->“扩展程序”,然后单击“立即更新扩展程序”时,扩展程序不会获取新版本。服务器确实收到了对“localhost:3000/clients/chrome/updates.xml”的请求,但没有收到任何有关新extension.crx文件的请求。我在这里做错了什么?

代码

让我带你走一遍这段代码,以便使其可重现:

$ tree

.
|-- clients
|   `-- chrome
|       |-- extension
|       |   `-- manifest.json
|       |-- extension.crx
|       |-- extension.pem
|       `-- updates.xml
`-- web.js

这个扩展实际上只是一个清单文件。

manifest.json

{
  "name": "testing auto-updates",
  "version": "1.0",
  "update_url": "http://localhost:3000/clients/chrome/updates.xml"
 }

如您所见,我是在引用一个update_url以实现自动更新的功能。

updates.xml

<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='fkphbmkcjefhhnnlhhjlnkellidponel'>
    <updatecheck codebase='http://localhost:3000/clients/chrome/extension.crx' version='1.0' />
  </app>
</gupdate>

打包扩展会创建extension.crxextension.pem
我还制作了一个简单的node.js服务器来提供这些文件:

web.js

var express = require('express');

var app = express.createServer(express.logger());

/* ROUTES */

app.get('/clients/chrome/extension.crx', function(request, response)
{
    response.contentType('application/x-chrome-extension');
    response.sendfile('clients/chrome/extension.crx');
});

app.get('/clients/chrome/updates.xml', function(request, response)
{
    response.sendfile('clients/chrome/updates.xml');
});

/* ROUTES END */

var port = process.env.PORT || 3000;

app.listen(port, function() {
  console.log("Listening on " + port);
});

好的,让我们来测试一下。首先,启动服务器:

$ node web.js

Listening on 3000

通过访问http://localhost:3000/clients/chrome/extension.crx来安装扩展。第一次尝试此部分完美地运作。服务器记录了请求:

127.0.0.1 - - [Thu, 26 Apr 2012 22:25:47 GMT] "GET /clients/chrome/extension.crx HTTP/1.1" 304 - "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/11.10 Chromium/18.0.1025.151 Chrome/18.0.1025.151 Safari/535.19"

让我们修改扩展:

  1. 在 manifest.json 中,将 version 设置为 1.1(而不是 1.0)。
  2. 在 updates.xml 中,将 version 设置为 1.1(而不是 1.0)。
  3. 使用与第一次相同的 extention.pem 文件重新打包扩展。
  4. 创建新的 extension.crx 文件。
  5. 单击 工具->扩展程序->立即更新扩展程序

人们期望在 工具->扩展程序 中看到扩展的版本号更改为 1.1。

但实际上,什么都没有发生。服务器收到了对 updates.xml 的请求,但没有收到对 extension.crx 的请求。

2个回答

2
我认为错误在于您的web.js文件如何提供“updates.xml”。我的推理如下:
  • 我重复了您的设置,并看到了同样缺少更新的情况。
  • 然后,我进行了第二个测试,仅使用我的公共Dropbox文件夹,一切都很完美。
  • 最后,我进行了另外两个测试:一个是使用由Node托管的“updates.xml”,指向由Dropbox托管的文件,另一个是使用由Dropbox托管的“updates.xml”,指向由Node托管的crx文件。

结果是,无论谁托管crx文件,只要由Node提供“updates.xml”,Chrome就无法正确更新扩展程序;而只要由Dropbox提供“updates.xml”,一切都很好(我确实更改了清单中的“update_url”,并为每次尝试重新构建/上传扩展程序)。

为什么会发生这种情况还是一个很大的谜团。以下是我在Chrome中获取“updates.xml”时获得的HTTP响应标头(通常使用地址栏;我没有嗅探实际的网络流量从更新操作,只是模拟它):

Dropbox:

HTTP/1.1 200 OK
Server: nginx/1.0.14
Date: ...
Content-Type: application/xml
Transfer-Encoding: chunked
Connection: keep-alive
x-robots-tag: noindex,nofollow
etag: ...
pragma: public
cache-control: max-age=0
Content-Encoding: gzip

Node.js:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/xml
Date: ...
Cache-Control: public, max-age=0
Last-Modified: ...
ETag: "..."
Accept-Ranges: bytes
Content-Length: 284
Connection: keep-alive

我认为这可能与端口有关(也许 Chrome 不喜欢从非 80 端口更新?),现在我刚刚发现,从我的自己的 Apache 服务器的 80 端口提供 updates.xml 和 crx 文件会导致与 Node 观察到的问题完全相同的故障。

我希望我能给你一个确切的答案,但也许你可以运行一些 Dropbox 测试,最终发现他们做了什么不同的事情,使得 Chrome 喜欢他们的更新文件。


至少我在Dropbox的成功证实了一种可能性,即Chrome强制执行HTTPS的要求并没有被记录下来,这是我之前的猜测之一,因为Dropbox在HTTP和HTTPS上同样表现良好。 - apsillers
这是最奇怪的事情:我本来想尝试使用各种标头并查看它会产生什么差异,但是第一次尝试时,这个东西就可以工作了,而且没有进行任何修改...如果我发现我在第一次尝试中搞砸了什么,我会回复的。 - Shawn
我的另一个理论是,1.1 CRX文件需要被命名为与原始的1.0文件不同的名称?这是我能想到的唯一一件我没有检查过并且在我的测试中可能做得不同的事情。 - apsillers

1

由于它获取了您的XML并且没有更新扩展名,因此它可能不喜欢您更新的XML中的某些内容。我最好的猜测是您的“appid”与已安装的扩展程序的应用程序ID不匹配。在页面chrome://extensions上查看已安装扩展程序的“ID”,并验证该值是否与update.xml中的值相匹配。


实际上,问题已经消失了,而我并没有改变任何东西(据我所知)。换句话说,我解决了它,但我不知道如何解决的。你的理论显然是完全正确的,但我不记得是否更改了应用程序ID,因此无法确认... - Shawn

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