如何在Express中设置自定义网站图标?

164

我最近开始使用Node.js,而在app.js文件中有这一行代码:

app.use(express.favicon());

现在,我该如何设置自己的自定义favicon.ico图标?


5
请确保正确清除浏览器缓存,否则您可能无法看到更改。 - vsync
在 Express 4 上使用 app.use(express.favicon()) 会得到以下提示:大多数中间件(如 favicon)不再与 Express 捆绑在一起,必须单独安装。请参阅 github.com/senchalabs/connect#middleware。或者,您可以使用以下代码来禁用 favicon:app.get('/favicon.ico', (req, res) => res.status(200)) Express js prevent GET /favicon.ico - user
你不需要任何中间件,只需一行代码即可检查此答案:Stack Overflow - 27px
15个回答

276

在Express 4中

安装favicon middleware,然后执行以下操作:

var favicon = require('serve-favicon');

app.use(favicon(__dirname + '/public/images/favicon.ico'));

或者更好的方法是使用 path 模块:

app.use(favicon(path.join(__dirname,'public','images','favicon.ico')));

请注意,此解决方案同样适用于Express 3应用程序。

在Express 3中

根据API,.favicon接受一个位置参数:

app.use(express.favicon("public/images/favicon.ico")); 

大多数情况下,您可能需要这样做(如vsync所建议的):
app.use(express.favicon(__dirname + '/public/images/favicon.ico'));

或者更好的方法是使用path模块(正如Druska建议的那样):

app.use(express.favicon(path.join(__dirname, 'public','images','favicon.ico'))); 

为什么 faviconstatic 更好

根据 包描述

  1. 该模块会将图标缓存在内存中,通过跳过磁盘访问来提高性能。
  2. 该模块提供了一个基于图标内容而非文件系统属性的 ETag
  3. 该模块将使用最兼容的 Content-Type 进行服务。

1
谢谢!你介意开个问题让我去看一下吗?希望只是路径的问题,特别是path.join(__dirname, "public")会导致字符串连接而没有分隔符?样本越小,我们就能越快地解决这个问题(所以如果可以,请只提供join部分)。 - Benjamin Gruenbaum
使用另一个中间件(由未来可能不会维护的人维护)而不是更简单的方式(由Eduardo解释)有什么好处? - LucaM
4
首先,好问题!serve-favicon由我们(Node.js基金会)和Doug(维护express的人)维护,也就是说,它是由编写和维护express本身的同一群人编写和维护的。您可以查看readme了解其原因,但基本上包括日志记录、缓存、ETag处理和正确的Content-Type。您可以在此处查看它的操作方式here。您认为将此编辑到答案中有价值吗? - Benjamin Gruenbaum
1
感谢Benjamin澄清了favicon提供的功能。虽然不是必需的,但我会在被接受的答案中写出来。 - LucaM

74

无需额外的中间件。只需使用:

app.use('/favicon.ico', express.static('images/favicon.ico'));

4
没错,这就足够了,而且这是正确的答案,因为为此添加额外的中间件感觉过于繁琐。 - jlstr
1
@jlstr 这只是20行代码,你所说的“过度设计”是什么意思)) 而且这是服务器端的代码,所以小依赖项的数量并不重要。而且提到的中间件提供了以下功能:1)内存缓存 2)设置适当的ETag 3)设置适当的Content-Type - maxkoryukov
我已经有了app.use(express.static("dist"));,可以从“dist”文件夹中提供所有js、img和css文件的服务,如/img/some_image.png/js/my_file.js,以及在<head>标签中的<link rel="shortcut icon" href="/img/favicon.ico">。但是在Azure上的Node/MongoDB应用程序中仍然会出现404错误,失败的请求为GET /favicon.ico。这是解决方案吗:app.use(express.static("dist"));后面跟着app.use('/favicon.ico', express.static('/img/favicon.ico'));?编辑:我在本地环境中尝试过这个方法,结果http://localhost:3000/favicon.ico返回Cannot GET /favicon.ico - user1063287
回答我的评论问题,这对我似乎有效:app.use('/favicon.ico', express.static('dist/img/favicon.ico'));我的现有app.use(express.static("dist"));之上。 - user1063287
请注意,您应该使用>require('serve-favicon')<模块,因为它会生成缓存,从而防止从存储中读取文件。 - Daniel
我认为缓存应该由CDN处理。 - Eduardo

32

不需要自定义中间件?! 在express中:

 //you probably have something like this already    
app.use("/public", express.static('public')); 

然后将您的网站图标放在public文件夹中,并在HTML文件的标签中添加以下行:

<link rel="icon" href="/public/favicon.ico">

4
那是DaafVader。这个方法有效。我的设置是:app.use(express.static('public'))。我把我的网站图标保存在public文件夹内的img文件夹里。在我的HTML文件的<head>部分,我使用了<link rel="icon" href="/img/favicon.ico">,其中favicon.ico是我网站图标的文件名。 - Nhon Ha
对我来说,由于我在模板引擎的目录中,所以我必须使用../public/favicon.ico - Oliver Dixon

18

防止错误的笑脸网站图标:

 //const fs = require('fs'); 
 //const favicon = fs.readFileSync(__dirname+'/public/favicon.ico'); // read file
 const favicon = new Buffer.from('AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA/4QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREQAAAAAAEAAAEAAAAAEAAAABAAAAEAAAAAAQAAAQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD8HwAA++8AAPf3AADv+wAA7/sAAP//AAD//wAA+98AAP//AAD//wAA//8AAP//AAD//wAA', 'base64'); 
 app.get("/favicon.ico", function(req, res) {
  res.statusCode = 200;
  res.setHeader('Content-Length', favicon.length);
  res.setHeader('Content-Type', 'image/x-icon');
  res.setHeader("Cache-Control", "public, max-age=2592000");                // expiers after a month
  res.setHeader("Expires", new Date(Date.now() + 2592000000).toUTCString());
  res.end(favicon);
 });

如何更改上面代码中的图标

可以在这里创建一个图标:http://www.favicon.cc/ 或者这里:http://favicon-generator.org

然后将其转换为base64,可以在这里完成:http://base64converter.com/

最后替换图标的base64值即可。

如何创建个性化的网站小图标

使用Photoshop或Inkscape制作图标,可能需要先使用Inkscape,然后在Photoshop的图像->调整菜单中进行色彩校正和增强。

如果需要快速制作图标,可以前往http://www.clker.com/选择一些矢量图形,并下载为SVG格式。然后将其导入到Inkscape (https://inkscape.org/) 中,更改颜色或删除部分内容,也可以从另一个矢量图形中添加一些元素。最后选择要导出的部分,点击文件->导出,选择像16x16这样的大小用于制作网站小图标,128x128或256x256用于进一步编辑。ICO文件可以包含多个图标尺寸,除了16x16像素的小图标外,还可以包含高质量的链接图标。

最后可能需要在Photoshop中对图像进行进一步增强,如色彩增强、斜角效果或圆形遮罩等。

然后将该图像上传到生成网站小图标的其中一个网站上。也有一些Windows程序可用于编辑图标,如https://sourceforge.net/projects/variicons/

要将网站小图标添加到网站中,只需将favicon.ico作为一个文件放在域的根目录中即可。例如,在Node.js中,可以将其放置在包含静态文件的public文件夹中。它不必像上面的代码那样特别,只需要是一个简单的文件即可。


1
我最喜欢这种方法。我只是使用文件来提供服务,而不是base64:fs.createReadStream(“./public/favicon.ico”)。pipe(res); - DaafVader
2
既然你已经在使用Express,为什么不直接使用express.favicon呢?为什么要创建一个完整的路由,如果你同样可以使用静态文件夹呢?除此之外,那个神奇的字符串(你的笑脸)并没有让你的情况变得更好。 - SubliemeSiem
1
您不需要任何代码来放置网站图标。只需将其作为文件放置在静态文件目录中即可。 - Shimon Doodkin

8
app.use(express.favicon(__dirname + '/public/images/favicon.ico')); 

我在本地运行时没有使用__dirname +,但是在我的部署服务器上无法使其工作。


尝试使用 app.use(express.favicon('./public/images/favicon.ico')); - Alexis Diel
@AlexisDiel 为什么这样说? - Pierre Arlaud

4
如果您使用的是Express > 4.0版本,您可以选择使用serve-favicon。请参考serve-favicon

11
为什么我们应该选择 serve-favicon? - Black

3
如果您已经设置了静态路径,那么在视图中只需使用<link rel="icon" href="/images/favicon.ico" type="image/x-icon">即可,无需其他任何内容。请确保您的图像文件夹位于公共文件夹中。

2
请确保在开发过程中在Google Chrome中使用127.0.0.1而不是localhost,出于某种原因,这对我有用。 - cprcrack

2

如果以上两种方法都不起作用,您可以尝试以下方法!
确保您的favicon.ico文件在public/icons目录下或相应更改路径。
如果未导入路径

const path = require('path') ; 

那么,
app.get("/favicon.ico", (req, res) => {
  return res.sendFile(path.join(__dirname + "/public/icons/favicon.ico"));
});

2

如果您想要一个不涉及外部文件并且不使用express.static的解决方案(例如,一个超轻量级的单文件Web服务器和网站),您可以使用serve-favicon并将您的favicon.ico文件编码为Base64。像这样:

const favicon = require('serve-favicon');
const imgBuffer = new Buffer.from('IMAGE_AS_BASE64_STRING_GOES_HERE', 'base64');
// assuming app is already defined
app.use(favicon(imgBuffer));

IMAGE_AS_BASE64_STRING_GOES_HERE 替换为将您的网站图标文件编码为Base64的结果。有很多在线网站可以完成这个过程,您可以搜索一下。
请注意,在localhost上查看效果可能需要重启服务器和/或浏览器,并且在Web上查看效果可能需要进行强制刷新/清除浏览器缓存。

2

In app.js:

app.use(express.static(path.join(__dirname, 'public')));

假设图标位于"/public/images/favicon.ico",请在HTML的头部添加以下链接: 。最初的回答。
<link rel='icon' href='/images/favicon.ico' class='js-favicon'>

这在一个使用以下命令自动生成的项目中运行良好:

express my-project

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