标签归档:图片

(使用 HTML、JavaScript、Flask 或 Nginx)为丢失的图片显示默认图片

当在 HTML 页面上显示图片时,如果图片不存在,我们通常需要显示一个默认图片。

假设我们的图片路径在 /imgs 下,默认图片为 /imgs/default.jpg,下面是一些常见的处理方法示例。

Solution 1: HTML / JavaScript

最简单的,你可以使用 <img> 元素的 onerror 属性来设置默认图片:

<img src="/imgs/cat.jpg" onerror="this.src='/imgs/default.jpg'">

类似的,你也可以使用 JavaScript(jQuery)监听 img 元素的 error 事件(当图片地址无效时浏览器会触发这个事件):

$('img').on("error", function() {
  $(this).attr('src', '/imgs/default.jpg');  // 替换为默认图片
});

Solution 2: Flask

除此之外,你也可以在服务器端处理,以 Flask 为例,你可以写一个自定义视图函数来加载图片:

import os
from flask import send_from_directory

# ...

@app.route('/img/<path:filename>')
def get_image(filename):
    img_path = os.path.join(images_path, filename)  # 获取图片路径

    if not os.path.exists(img_path):  # 判断图片文件是否存在
        return send_from_directory(os.path.join(images_path, '/imgs/default.jpg'))
    return send_from_directory(img_path)

在模板里,使用这个视图函数获取图片 URL:

<img src="{{ url_for('get_image', filename='imgs/' + image.filename) }}" >

Solution 3: Nginx

在生产环境下,出于性能的考虑,我们通常会使用 Web 服务器(比如 Nginx / Apache) 来服务(serve)静态文件。以 Nginx 为例,你可以使用 try_files 指令来设置默认图片:

location /imgs/ {
    try_files $uri /imgs/default.jpg;
}

附注:本文改写自我的SO 回答

让 CKEditor 图片响应式(responsive)

通过 CKEditor 上传并插入图片后,CKEditor 的图片部件(widget)会在图片的 <img> 元素里插入行内样式定义来设置图片的宽高,这会导致响应式布局失效:图片因为被固定了宽高,在窗口缩小后会超出外层元素。生成的 HTML 代码示例如下:

<img alt="hello" src="/images/hello.jpg" style="height:300px; width:500px" />

对于这个问题,有三种解决方法:

方法 1:设置 CSS

最简单的解决方法是在 CSS 文件里加入下面的代码:

img {
    max-width: 100%;
    height: auto !important;
}

这会重写 CKEditor 生成的行内 CSS。

方法 2:使用插件 Enhanced Image

你可以使用加强版的图片部件插件 Enhanced Image(Image2)来替代原有的图片部件,同时确保 CKEditor 的版本大于 4.3。

(未测试。)

方法 3:使用 JavaScript

如果你使用 Bootstrap,这里还有另一种方法:

CKEDITOR.on('instanceReady', function (ev) {
    ev.editor.dataProcessor.htmlFilter.addRules( {
        elements : {
            img: function( el ) {
                // Add bootstrap "img-responsive" class to each inserted image
                el.addClass('img-responsive');
        
                // Remove inline "height" and "width" styles and
                // replace them with their attribute counterparts.
                // This ensures that the 'img-responsive' class works
                var style = el.attributes.style;
        
                if (style) {
                    // Get the width from the style.
                    var match = /(?:^|\s)width\s*:\s*(\d+)px/i.exec(style),
                        width = match && match[1];
        
                    // Get the height from the style.
                    match = /(?:^|\s)height\s*:\s*(\d+)px/i.exec(style);
                    var height = match && match[1];
        
                    // Replace the width
                    if (width) {
                        el.attributes.style = el.attributes.style.replace(/(?:^|\s)width\s*:\s*(\d+)px;?/i, '');
                        el.attributes.width = width;
                    }
        
                    // Replace the height
                    if (height) {
                        el.attributes.style = el.attributes.style.replace(/(?:^|\s)height\s*:\s*(\d+)px;?/i, '');
                        el.attributes.height = height;
                    }
                }
        
                // Remove the style tag if it is empty
                if (!el.attributes.style)
                    delete el.attributes.style;
            }
        }
    });
});

出处地址

需要注意的是,如果你使用 Bootstrap 4,需要把第 6 行的 img-responsive 换成 img-fluid。

(未测试。)