Что делать, если у вас есть коллекция изображений, хранящаяся в общей сетевой папке, и вы хотите динамически отображать на веб-сайте последнее отредактированное изображение?

Я оказался в такой ситуации, когда мы постепенно перешли на использование файлов .pdf вместо .tif для наших чертежей плана. Во время этого перехода иногда новое изображение помещалось в ту же папку, что и старое изображение. У них будет одинаковое имя, но разные расширения файлов. Обычно более новым является PDF-файл, но я не мог рассчитывать на то, что так будет всегда. Итак, мне нужно было проверить дату последнего изменения, чтобы определить, какое из них было последним официальным изображением.

ASP.NET-подход:

У меня есть приложение ASP.NET, которое извлекает эти изображения. Вот как я это сделал с помощью C#:

//Check if file exists on the webserver
bool imageFound = false;
string folderName = "nameoffolder";
string fileName = "nameoffile";
string searchFilePath = Path.Combine(@"\\servername\c$\path\to\fileshare\" 
+ folderName);

if (Directory.Exists(searchFilePath))
{
  //Get the last modified file with the fileName, ignoring the extension    
  DirectoryInfo directoryInfo = new DirectoryInfo(searchFilePath);
  FileInfo selectedFile = directoryInfo.GetFiles(fileName + ".*")
  .OrderByDescending(f => f.LastWriteTime).FirstOrDefault();
    
    if (selectedFile != null && selectedFile.Length > 0)
    {
        imageFound = true;
    }
}

Это было довольно просто, поскольку .NET работает на сервере и имеет прямой доступ к файлам, а в кодовую базу встроено множество опций для работы с ними. Легко делать такие причудливые вещи, как поиск по имени файла с подстановочным знаком для расширения файла (.*), сортировать результаты по убыванию времени последней записи, а затем выбирать первый файл в списке.

JavaScript-подход:

На стороне клиента сделать то же самое сложнее. У меня есть другое приложение, которому нужно выполнить поиск по этой же коллекции изображений с помощью JavaScript. Единственный способ для клиента проверить изображения на сервере — сделать запрос. Я делаю это с помощью Fetch API для JavaScript.

var src = 'https://URL/to/fileshare/folderName/fileName';
fetch(src + '.tif', { method: 'HEAD' })
    .then(function(response) {
        if (response.ok) {
            var lastmod = response.headers.get('Last-Modified');
            var lastmodDate = Date.parse(lastmod);
            tifmod = lastmodDate;
        }
    });

В отличие от C#.NET, я не могу использовать подстановочный знак для расширения и получить то, что мне нужно, за один шаг. Вместо этого мне приходится получать данные дважды, по одному разу для каждого возможного расширения. Затем, если файл существует, я сохраняю дату его последнего изменения в переменной. Наконец, я сравниваю все даты и открываю файл, самый последний.

var latestmodDate = Math.max(tifmod, pdfmod);
if (pdfmod == latestmodDate) {
    window.open(src + '.pdf', "_blank");
} else if (tifmod == latestmodDate) {
    window.open(src + '.tif', "_blank");
}

Поскольку мне нужно выполнить несколько запросов, я старался не загружать каждый раз все изображение, поэтому передаю по сети меньше информации. Я просто просматриваю заголовки, используя метод HEAD (в отличие от метода GET по умолчанию).



Если изображения хранятся на другом сервере, чем ваше веб-приложение, вам необходимо убедиться, что целевой сервер настроен так, чтобы разрешить прохождение запроса. Это можно сделать, добавив собственные заголовки ответов HTTP в виртуальный каталог с помощью IIS.

Обработка устаревших изображений:

Наконец, веб-браузеры часто кэшируют изображения после того, как люди их загружают, чтобы ускорить поиск. У нас есть ночной процесс, который заменяет изображения на нашем веб-сервере, если есть более новые версии. Но если пользователь просматривал один и тот же проект в веб-приложении два дня подряд, вчерашнее изображение все равно будет храниться в его кеше, и он не увидит новое.

Мы обошли эту проблему, добавив временную метку в конец URL-адреса изображения.

ImageURL = "https://URL/to/fileshare/folderName/" + selectedFile.Name 
+ "?timestamp=" + DateTime.Now.ToFileTime()

Теперь браузер воспринимает каждый запрос как уникальный и каждый раз загружает новую версию изображения.