【问题标题】:Changing the Image in folder does not reflect changes in browser更改文件夹中的图像不会反映浏览器中的更改
【发布时间】:2017-05-15 12:01:15
【问题描述】:

我在做什么:

我正在使用 mongodb 数据库、nodejs 和 angular 4 显示图像文件中的图像。图像显示得很好。

问题:

我显示的图像的路径是assets/Images/1.jpg。 该路径来自数据库。

现在,我转到文件夹 assets/Images 并删除 1.jpg。然后我将新图片上传到此文件夹,然后将新上传的图片重命名为 1.jpg。

但浏览器仍在显示旧图像。

我尝试了什么:

我尝试刷新浏览器选项卡。但它仍然显示旧图像。

所以,正如this post 中所述,我尝试了empty cache and hard reload。浏览器仍然显示旧图像。

然后我重新启动了服务器。正如预期的那样,浏览器会向我显示新图像。

我想要什么:

我希望浏览器在我复制粘贴新图像后立即显示更改后的图像,删除旧图像并重命名新图像。

如果不可能突然改变,那么我希望浏览器在以编程方式刷新页面时显示新图像。

重现问题的示例

您可以在此链接下载示例:https://drive.google.com/file/d/0B5WyqSALui0bekJhTGtudWNOd28/view?usp=sharing

如何使用示例运行应用程序

  1. 从上述链接下载示例文件。
  2. 解压文件。
  3. 打开 git bash 或终端并导航到 image-sample 文件夹
  4. 运行npm install 命令。
  5. 安装依赖后,cd node-files,然后cd seed
  6. 运行node image-seeder 命令。这将在 mongodb 中创建一个示例数据库,然后插入示例数据。
  7. 运行cd .. 两次来到原文件夹,然后
  8. 通过npm start运行应用程序
  9. 打开浏览器并在地址栏中输入localhost://3000。您应该会看到该图像。
  10. 现在浏览 src/assets/Images 文件夹
  11. 删除 1.jpg
  12. 将2.jpg重命名为1.jpg,然后查看浏览器。图片不会改变。
  13. 刷新浏览器窗口。仍将显示旧图像。
  14. 重启服务器就可以看到修改后的图片了。

代码和说明

首先我使用

创建了 Angular 应用程序
ng new image-sample

然后我在package.json中添加了一些依赖如下:

"body-parser": "^1.17.1",
"cookie-parser": "^1.4.3",
"core-js": "^2.4.1",
"express": "^4.15.2",
"fs": "0.0.1-security",
"mongoose": "^4.9.9",
"morgan": "^1.8.1",
"path": "^0.12.7"

我还修改了脚本如下:

"scripts": {
    "ng": "ng",
    "start": "npm run serve-build",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "build:nodeserver": "ng build && cp nodeserver/* dist",
    "build:nodeserver-prod": "ng build -prod && cp nodeserver/* dist",
    "serve-build": "npm run build:nodeserver && cd dist && node server.js",
    "serve-build-prod": "npm run build:nodeserver-prod && cd dist && node server.js"
},

然后我使用以下命令安装这些依赖项:

npm install

然后我在image-sample目录下创建了一些文件夹和文件如下:

nodeserver
   |-- server.js

node-files
   |--models
       |-- db.js
       |-- Image.js
   |--api
       |-- image.js
   |--seed
       |-- image-seeder.js

这是上述文件的内容:

nodeserver/server.js

var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var path = require('path');
var fs = require('fs');

require('../node-files/models/db');

var image = require('../node-files/api/image');

var app = express();
var staticRoot = __dirname + '/';

app.set('port', (process.env.PORT || 3000));

app.use(express.static(staticRoot));

app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(cookieParser());

app.use(function(req, res, next){

    // if the request is not html then move along
    var accept = req.accepts('html', 'json', 'xml');
    if(accept !== 'html'){
        return next();
    }

    // if the request has a '.' assume that it's for a file, move along
    var ext = path.extname(req.path);
    if (ext !== ''){
        return next();
    }

    fs.createReadStream(staticRoot + 'index.html').pipe(res);

});

app.use('/api/image', image);

app.listen(app.get('port'), function() {
    console.log('app running on port', app.get('port'));
});

node-files/models/db.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/sampleimagedb')

节点文件/模型/Image.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var imageSchema = new Schema({
    url: {type: String, required: true},
    width: {type: Number, required: true},
    height: {type: Number, required: true}
});

var Image = module.exports = mongoose.model('Image', imageSchema);

module.exports.getAllImages = function(callback){
    Image.find().lean().exec(function(err, images){
        if (err) return callback(err, null);
        callback(null, images);
    });
};

node-files/api/image.js

var express = require('express')
var router = express.Router();

var Image = require('../models/Image');

router.get('/', function(req, res, next) {

    Image.getAllImages(function(err, images) {
        if(err) { return res.status(400).json(err); }
        else { res.status(200).json(images); }
    });

});

module.exports = router;

node-files/seed/image-seeder.js

var Image = require('../models/Image');

var mongoose = require('mongoose');
mongoose.connect('localhost:27017/sampleimagedb');

var images = [
    new Image({
        url: 'assets/Images/1.jpg',
        width: 300,
        height: 200
    })
];

var done = 0;

for(var i = 0; i < images.length; i++)
{
    images[i].save(function(err, result){
        done++;
        if(done == images.length){
            exit();
        }
    });
}

function exit() {
    mongoose.disconnect();
    console.log(images.length + ' Image(s) added to the database');
}

然后在角度方面,我在src/app 下创建了一个名为models 的文件夹。我在其中添加了Image.ts 文件,如下所示:

export class Image
{
    url: string;
    height: number;
    width: number;

    constructor(url: string, height: number, width: number) {
      this.url = url;
      this.height = height;
      this.width = width;
    }
}

我在src/app 文件夹中创建了一个services 文件夹。然后我使用 angular-cli 工具在 services 文件夹中添加了一个名为 ImageService 的服务,如下所示:

ng g service image

这会生成两个文件,其中一个是image.service.ts,看起来像:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';

import { Image } from '../app.component';

@Injectable()
export class ImageService {

  constructor(private http:Http) { }

  public image: Image

  getImages(): Observable<Image[]> {
    return this.http.get('/api/image')
                    .map(res => res.json());
  }

}

然后我在app.module.ts 的提供者部分添加了这项服务,如下所示:

providers: [ImageService],

然后在app.component.ts 文件中我调用ImageService 如下:

import { Component, OnInit } from '@angular/core';
import { ImageService } from './services/image.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{

    images: Image[];

    ngOnInit() {
        this.imageService.getImages()
            .subscribe(
                response => this.images = response,
                error => console.log(error)
            );;
    }

    constructor(private imageService: ImageService) {

    }

}

最后在app.component.html:

<div *ngFor="let image of images">
    <img [src]="image.url" style="left:0px;top:0px;" 
         [style.width.px]="image.width" [style.height.px]="image.height"/>
</div>

【问题讨论】:

  • 您是否在使用 cloudfire 或任何类似的可能正在缓存的东西?
  • @webbm 不。我正在使用本地主机。
  • 好的,我已经通读了一遍,虽然我自己不使用猫鼬,但它正在将图像加载到 RAM 中是否正确?更改文件系统后,您似乎需要将映像重新加载到 RAM 中。
  • @webbm 我不是那么高级的程序员。但我应该说猫鼬只是为角度应用程序提供了图像路径。并使用该路径角度从路径中的指定文件夹获取图像。正如我告诉过你的那样,我不是高级程序员,我不知道如何将图像重新加载到 RAM 中。你能告诉我怎么做吗?
  • 您可以在进行更改后尝试重新启动服务器吗?因为当您使用 express.static 时,文件会缓存在服务器上,我正在寻找一些东西来清理它。你能检查一下是否有效吗?

标签: javascript node.js mongodb angular


【解决方案1】:

你的问题是其他的。

您正在运行 ng 构建器并将输出设置为 /dist,然后将静态文件复制到 dist 文件夹,然后您必须更改以下位置的图像:image-sample/dist/assets/images。尝试在此文件夹上进行测试,它会起作用。

您的问题是关于构建的,您必须观察 /src 上更改的文件,并且必须在更改后再次运行构建任务,或者您可以更改 dist 上的文件,但我不建议这样做,因为当再次运行 build,dist 上的文件被覆盖。

因此,您必须改进您的任务运行程序和构建过程,以使您的应用程序更好地按照您的意愿工作。

【讨论】:

  • 我已经测试过了。你说的对。当我更改 dist/assets/images 中的图像并刷新浏览器窗口时,图像发生了变化。
  • 第一件事。我不知道 package.json 文件中的配置脚本部分。构建配置从这个站点复制:tattoocoder.com/angular2-giving-your-cli-server
  • 我不想将所有内容复制到 dist 文件夹(如果可能的话)。因为我不喜欢在上传图像时重新启动服务器的想法。正如您提到的,如果我更改 dist/assets/Images 中的图像,那么每当服务器重新启动时,dist 的内容就会被覆盖。所以,我必须对资产/图像进行更改,然后重新启动服务器。所以,我不得不重新启动我不喜欢的服务器。有没有其他办法?
  • 我使用 gulp 来完成我的项目任务,通常我使用 gulp.watch 来查看 src 文件夹中更改的文件并将这些文件复制到 dist 文件夹。我正在寻找 ng builder 的观察者,但这对我来说是新的。
  • 感谢您抽出宝贵时间支持我。让我告诉你一件事。我在 package.json 中的脚本部分有一些问题。如果我无论如何更改我的代码,那么我必须手动重新启动服务器。在将节点支持添加到 angular4 应用程序之前,当我更改代码时,服务器会自动重新启动。您也可以检查一下吗?
猜你喜欢
  • 2017-10-08
  • 2013-02-07
  • 2021-03-06
  • 2017-01-11
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
相关资源
最近更新 更多