Я запускаю coldfusion8/MySQL5.0.88
, и у меня есть поиск товаров, для которого мне нужно загрузить и изменить размер изображений из различных внешних источников, прежде чем отображать их.
Хотя в основном я могу сделать это, когда продукты создаются (а не ищутся), я не могу гарантировать, что все изображения будут доступны в измененном формате с моего сервера, поэтому мне нужен какой-то запасной вариант внутри поиска продукта.
Прямо сейчас я проверяю, доступно ли изображение на сервере, и если нет, я запускаю процедуру для захвата и изменения размера изображения следующим образом:
// check if image is available
<cfif results.typ NEQ "img" AND results.typ NEQ "alt">
<cfif results.bildpfad neq "" AND results.bilddateiname neq "">
<cfset imgSuccess = form_img_handler.upload
( command = "upload_search"
, imgPath = results.bildpfad
, imgFile = results.bilddateiname
, sellerILN = results.iln
, cookie = variables.screenWidth
)/>
<cfif imgSuccess EQ "false">
<cfset variables.imgFail = "true">
</cfif>
</cfelse>
<cfset variables.imgFail = "true">
</cfif>
// missing img
<cfif variables.imgFail EQ "true">
<cfoutput><div class="resultsImgWrap noImgFound"></div></cfoutput>
<cfset variables.imgFail = "false">
<cfelse>
// show image
<cfoutput><div class="resultsImgWrap"><img src="#variables.imageSrc#" /></div></cfoutput>
</cfif>
Функция upload
обрабатывает запрос cfhttp
и изменение размера и возвращает true/false
.
Мне интересно, можно ли использовать cfthread
в этом контексте, поэтому, когда пользователь выполняет поиск, я вывожу разметку, включая правильные URL-ссылки, но извлечение/изменение размера/сохранение изображения в место назначения будет выполнено в cfthread
, в для ускорения отображения результатов для пользователя.
Вопрос:
Будут ли изображения отображаться после того, как cfthread
закончит обработку, или этот подход приведет к ошибке 404
при попытке загрузить изображение, которое не было создано (вероятно)? Существуют ли какие-либо другие способы показать что-то пользователю и позволить пользователю продолжить, пока изображения загружаются и обрабатываются?
Спасибо за материалы!
EDIT:
Хорошо. На основании ответов я пришел к следующему. Пока еще не работает, я думаю, что это идет в правильном направлении.
// check media log, if image is logged (already created), if so, load it, if not pull it from external
<cfif results.typ NEQ "img" AND results.typ NEQ "alt">
// check path and filename
<cfif results.bildpfad neq "" AND results.bilddateiname neq "">
// pull in
// arguments:
// cm = form
// pt = path to image
// fl = filename
// se = seller id
// ck = screen width (I'm using adaptive image sizes
// ax = origin
// gb = which image size to return
<cfset variables.imgSrc = expandPath("../services/img_handler.cfc") & "?method=up&cm=results&pt=" & results.bildpfad & "&fl=" & results.bilddateiname & "&se=" & results.id & "&ck=" & variables.screenWidth & "&ax=rm&gb=s">
<cfelse>
cfset variables.imgFail = "true">
</cfif>
</cfif>
<cfif variables.imgFail EQ "true">
<cfoutput><div class="resultsImgWrap noImgFound"><img src="../images/not_found.png"></div></cfoutput>
<cfset variables.imgFail = "false">
<cfelse>
<cfoutput><div class="resultsImgWrap"><a class="swipeMe" rel="external" href="#variables.zoomSrc#">
<img src="#variables.imageSrc#" class="adaptImg ui-li-thumb" /></a>
</div></cfoutput>
</cfif>
Таким образом, это проверит изображение в моем медиа-журнале, которое я запрашиваю, вместе с результатами (избегайте ненужной проверки s3 для существующего изображения). Если в журнале нет изображения, я проверяю, не является ли путь/имя файла пустым, и запускаю загрузчик изображений intelligent
, который делает следующее:
<cfcomponent output="false" hint="image handler">
<cffunction name="Init" access="public" returntype="any" output="false" hint="Initialize">
<cfreturn true />
</cffunction>
<cffunction name="upload" access="remote" output="false" hint="creates images and stores them to S3">
<cfargument name="cm" type="string" required="true" hint="" />
<cfargument name="pt" type="string" required="true" hint="" />
<cfargument name="fl" type="string" required="true" hint="" />
<cfargument name="se" type="string" required="true" hint="" />
<cfargument name="ck" type="string" required="true" hint="" />
<cfargument name="gb" type="string" required="false" hint="" />
<cfargument name="ax" type="string" required="false" hint="" />
<cfscript>
var LOCAL = {};
// arguments
LOCAL.command = cm;
LOCAL.imgPath = pt;
LOCAL.imgFile = fl;
LOCAL.sellerILN = se;
LOCAL.cookie = LSParseNumber(ck);
LOCAL.getBack = gb;
LOCAL.access = ax;
// s3
// commander
if ( LOCAL.command NEQ "" ) {
LOCAL.action = LOCAL.command;
} else {
LOCAL.action = "upload";
}
// s3 misc
LOCAL.bucketPath = Session.bucketPath;
LOCAL.bucketName = Session.bucketName;
LOCAL.acl = "public-read";
LOCAL.storage = "";
LOCAL.tempDirectory = expandPath( "../members/img/secure/" );
LOCAL.allow = "png,jpg,jpeg";
LOCAL.failedLoads = "";
LOCAL.altFailedLoads = "";
LOCAL.createBucket = "false";
LOCAL.errorCount = 0;
LOCAL.altErrorCount = 0;
LOCAL.cacheControl = 1;
LOCAL.contentType = "image";
LOCAL.httptimeout = "300";
LOCAL.cacheDays = "30";
LOCAL.storageClass = "REDUCED_REDUNDANCY";
LOCAL.keyName = "";
LOCAL.baseUrl = "http://www.baseurl.com";
LOCAL.imageSrc = "";
LOCAL.testFilePath = LOCAL.imgPath & LOCAL.imgFile;
LOCAL.fileExt = ListLast(LOCAL.testFilePath, ".");
LOCAL.runner = "s,m,l,xl";
LOCAL.worked = "true";
</cfscript>
// runner is the file size setter, in results I only create two sizes, during imports I create all four
<cftry>
<cfhttp timeout="45"
throwonerror="no"
url="#LOCAL.testFilePath#"
method="get"
useragent="Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12"
getasbinary="yes"
result="objGet">
<cfscript>
// set file sizes to create
if ( LOCAL.command EQ "upload_search" ){
if ( LOCAL.cookie LT 320 ) {
LOCAL.runner = "l,s";
}
else if ( LOCAL.cookie GTE 320 AND LOCAL.cookie LTE 767 ) {
LOCAL.runner = "l,m";
}
else if ( LOCAL.cookie GT 768 ) {
LOCAL.runner = "xl,m";
}
else if ( LOCAL.cookie GT 1280 ){
LOCAL.runner = "xl,l";
}
} else if ( LOCAL.command EQ "upload_import") {
LOCAL.runner = "xl,l,m,s";
}
// validate
if ( len(objGet.Filecontent) EQ 0 OR objGet.Mimetype EQ "text/html" ){
LOCAL.worked = "false length or mime";
} else if ( NOT listfindnocase(LOCAL.allow, LOCAL.fileExt ) ){
LOCAL.worked = "false wrong extension";
} else {
// create temp
LOCAL.objImage = ImageNew(objGet.FileContent);
LOCAL.basePath = LOCAL.tempDirectory & "_base_" & LOCAL.imgFile;
imageWrite( LOCAL.objImage, LOCAL.basePath, ".99");
LOCAL.base = imageRead( LOCAL.basePath );
LOCAL.imageSrc = LOCAL.tempDirectory;
// formats
// S = 100x127,
// M = 180x230,
// L = 290x370,
// XL = 870x1110
// portrait
if ( ImageGetWidth( LOCAL.base ) LT ImageGetHeight( LOCAL.base ) ){
for (LOCAL.i = 1; LOCAL.i LTE ListLen(LOCAL.runner,","); LOCAL.i = LOCAL.i+1){
LOCAL.lt = ListGetAt(LOCAL.runner, LOCAL.i, ",");
LOCAL.base = imageRead( LOCAL.basePath );
ImageSetAntialiasing(LOCAL.base,"on");
// default image width/height
LOCAL.height = Application.strConfig.respH[LOCAL.lt];
LOCAL.width = "";
ImageScaleToFit(LOCAL.base, LOCAL.width, LOCAL.height, "highestQuality");
LOCAL.filekey = LOCAL.lt & "_" & LOCAL.imgFile;
LOCAL.keyName = LOCAL.sellerILN & "/" & LOCAL.filekey;
LOCAL.filename = LOCAL.tempDirectory & LOCAL.filekey;
imageWrite( LOCAL.base, LOCAL.filename, ".99" );
// s3
Application.strObjs.s3.putObject(LOCAL.bucketName, LOCAL.filekey, LOCAL.contentType, LOCAL.httptimeout, LOCAL.cacheControl, LOCAL.cacheDays, LOCAL.acl, LOCAL.storageClass, LOCAL.keyName, LOCAL.imageSrc, "false" );
fileDelete( LOCAL.tempDirectory & LOCAL.lt & "_" & LOCAL.imgFile );
}
} else {
// same for landscape
...
}
}
// cleanup
fileDelete( LOCAL.tempDirectory & "_base_" & LOCAL.imgFile );
}
</cfscript>
// update media log
...
<cfcatch>
// dump errror message
</cfcatch>
</cftry>
// return image
<cfif LOCAL.access EQ "rm">
<cftry>
<cfscript>
if ( LOCAL.getBack EQ "s" ){
LOCAL.passPath = Session.bucketPath & Session.bucketName & "/" & LOCAL.sellerILN & "/" & ListGetAt(LOCAL.runner, Listlen(LOCAL.runner), ",") & "_" & LOCAL.imgFile;
} else if( LOCAL.getBack EQ "l" ) {
LOCAL.passPath = Session.bucketPath & Session.bucketName & "/" & LOCAL.sellerILN & "/" & ListGetAt(LOCAL.runner, 1, ",") & "_" & LOCAL.imgFile;
}
LOCAL.mime = "image/" & LOCAL.fileExt;
</cfscript>
<cfcontent type="#LOCAL.mime#" file="#LOCAL.passPath#" />
<cfcatch>
// dump errors
</cfcatch>
</cftry>
<cfelse>
<cfreturn LOCAL.worked>
</cfif>
</cffunction>
</cfcomponent>
Итак, я устанавливаю, какие размеры файлов я хочу создать LOCAL.runner
, и просматриваю этот список, изменяя размер базового изображения до заданных размеров изображения и сохраняя созданное изображение на s3.
Проблема: cfcontent
пытается вернуть изображение до его создания. Я получаю ошибку The file specified in contentTag does not exist
, когда запускаю приведенный выше код. Если я проверю на S3, изображение там, поэтому я предполагаю, что это проблема времени.
Спасибо за любые указания о том, как я могу заставить «cfcontent» ждать, пока изображение не будет создано!