Страницы: 1
Помогите исправить/дополнить скрипт загрузки файла на предмет "самоопределения" имени загружаемого файла, помещения файла в стандартный менеджер загрузок FF, ну и чтобы не спотыкался, если имя сохраняемого файла окажется в юникоде
$sURL - линк для загрузки
$sFolder - папка где сохранить файл
$sFile - имя загружаемого файла
(для FF ESR 10)
var Ci=Components.interfaces; var Cc=Components.classes; var oSrc=Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newURI("' & $sURL & '", null, null); var oDst=Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); oDst.initWithPath("' & $sFolder & "\\" & $sFile & '"); if(!oDst.exists()){oDst.create(0x00,0644);} var nsIWBP=Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist); nsIWBP.saveURI(oSrc,null,null,null,null,oDst);
Отсутствует
Господа! Просветите - почему не работает замена слешей на двойные:
var PathtoFile="E:\Program\Files\12345678.910"; var PathtoFile=PathtoFile.replace(/\\/g,"\\"); alert(PathtoFile);
Отсутствует
почему не работает замена слешей на двойные
Потому что \ – экранирующий символ.
Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела
Отсутствует
Потому что \ – экранирующий символ.
но каким образом тогда получить строку как она есть - с одинарными слешами, чтобы потом сработала замена?
var PathtoFile="E:\Program\Files\12345678.910".replace(/\\/g,"\\\\"); alert(PathtoFile);
ведь я её даже ввести не могу - получаю : "E:ProgramFiles12345678.910"
Отсутствует
но каким образом тогда получить строку как она есть - с одинарными слешами, чтобы потом сработала замена?
Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела
Отсутствует
Понятно, просто я рассчитывал, что должна сработать конструкция наподобие :
но, очевидно, нет.
Но, со слешами проще, а вот как узнать имя загружаемого файла из ссылки типа:
var SourceUrl = "http://www.site.com/........downloadid=8888"; var fileName = ... //
то есть, если волюнтаристски задать "file.ext", всё работает, но хотелось бы знать точно
Отсутствует
но хотелось бы знать точно
Придется отправить на сервер запрос, пример есть в chrome://browser/content/nsContextMenu.js:
nsContextMenu.prototype.saveLink() => this.saveHelper()
Или можно попробовать отправить HEAD-запрос и в конце проверить nsIChannel.URI.spec, пример: https://gist.github.com/Infocatcher/5327631 (в данном случае вполне хватит самой простой версии).
Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела
Отсутствует
Придется отправить на сервер запрос, пример есть в chrome://browser/content/nsContextMenu.js:
nsContextMenu.prototype.saveLink() => this.saveHelper()
Фунцию нашёл, но не никак не разберусь - на что указывает в данном случае "this"
// Save URL of clicked-on link. saveLink: function() { var doc = this.target.ownerDocument; urlSecurityCheck(this.linkURL, doc.nodePrincipal); this.saveHelper(this.linkURL, this.linkText(), null, true, doc); },
// Helper function to wait for appropriate MIME-type headers and // then prompt the user with a file picker saveHelper: function(linkURL, linkText, dialogTitle, bypassCache, doc) { // canonical def in nsURILoader.h const NS_ERROR_SAVE_LINK_AS_TIMEOUT = 0x805d0020; // an object to proxy the data through to // nsIExternalHelperAppService.doContent, which will wait for the // appropriate MIME-type headers and then prompt the user with a // file picker function saveAsListener() {} saveAsListener.prototype = { extListener: null, onStartRequest: function saveLinkAs_onStartRequest(aRequest, aContext) { // if the timer fired, the error status will have been caused by that, // and we'll be restarting in onStopRequest, so no reason to notify // the user if (aRequest.status == NS_ERROR_SAVE_LINK_AS_TIMEOUT) return; timer.cancel(); // some other error occured; notify the user... if (!Components.isSuccessCode(aRequest.status)) { try { const sbs = Cc["@mozilla.org/intl/stringbundle;1"]. getService(Ci.nsIStringBundleService); const bundle = sbs.createBundle( "chrome://mozapps/locale/downloads/downloads.properties"); const title = bundle.GetStringFromName("downloadErrorAlertTitle"); const msg = bundle.GetStringFromName("downloadErrorGeneric"); const promptSvc = Cc["@mozilla.org/embedcomp/prompt-service;1"]. getService(Ci.nsIPromptService); promptSvc.alert(doc.defaultView, title, msg); } catch (ex) {} return; } var extHelperAppSvc = Cc["@mozilla.org/uriloader/external-helper-app-service;1"]. getService(Ci.nsIExternalHelperAppService); var channel = aRequest.QueryInterface(Ci.nsIChannel); this.extListener = extHelperAppSvc.doContent(channel.contentType, aRequest, doc.defaultView, true); this.extListener.onStartRequest(aRequest, aContext); }, onStopRequest: function saveLinkAs_onStopRequest(aRequest, aContext, aStatusCode) { if (aStatusCode == NS_ERROR_SAVE_LINK_AS_TIMEOUT) { // do it the old fashioned way, which will pick the best filename // it can without waiting. saveURL(linkURL, linkText, dialogTitle, bypassCache, false, doc.documentURIObject); } if (this.extListener) this.extListener.onStopRequest(aRequest, aContext, aStatusCode); }, onDataAvailable: function saveLinkAs_onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) { this.extListener.onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount); } } function callbacks() {} callbacks.prototype = { getInterface: function sLA_callbacks_getInterface(aIID) { if (aIID.equals(Ci.nsIAuthPrompt) || aIID.equals(Ci.nsIAuthPrompt2)) { // If the channel demands authentication prompt, we must cancel it // because the save-as-timer would expire and cancel the channel // before we get credentials from user. Both authentication dialog // and save as dialog would appear on the screen as we fall back to // the old fashioned way after the timeout. timer.cancel(); channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT); } throw Cr.NS_ERROR_NO_INTERFACE; } } // if it we don't have the headers after a short time, the user // won't have received any feedback from their click. that's bad. so // we give up waiting for the filename. function timerCallback() {} timerCallback.prototype = { notify: function sLA_timer_notify(aTimer) { channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT); return; } } // set up a channel to do the saving var ioService = Cc["@mozilla.org/network/io-service;1"]. getService(Ci.nsIIOService); var channel = ioService.newChannelFromURI(makeURI(linkURL)); channel.notificationCallbacks = new callbacks(); let flags = Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS; if (bypassCache) flags |= Ci.nsIRequest.LOAD_BYPASS_CACHE; if (channel instanceof Ci.nsICachingChannel) flags |= Ci.nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY; channel.loadFlags |= flags; if (channel instanceof Ci.nsIHttpChannel) { channel.referrer = doc.documentURIObject; if (channel instanceof Ci.nsIHttpChannelInternal) channel.forceAllowThirdPartyCookie = true; } // fallback to the old way if we don't see the headers quickly var timeToWait = gPrefService.getIntPref("browser.download.saveLinkAsFilenameTimeout"); var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); timer.initWithCallback(new timerCallback(), timeToWait, timer.TYPE_ONE_SHOT); // kick off the channel with our proxy object as the listener channel.asyncOpen(new saveAsListener(), null); },
Отсутствует
Фунцию нашёл, но не никак не разберусь - на что указывает в данном случае "this"
Должен указывать на экземпляр new nsContextMenu().
Это из контекстного меню, используется так:
view-source:chrome://browser/content/browser.xul
<menupopup id="contentAreaContextMenu" pagemenu="start" onpopupshowing="if (event.target != this) return true; gContextMenu = new nsContextMenu(this, event.shiftKey); if (gContextMenu.shouldDisplay) updateEditUIVisibility(); return gContextMenu.shouldDisplay;" ... <menuitem id="context-savelink" label="&saveLinkCmd.label;" accesskey="&saveLinkCmd.accesskey;" oncommand="gContextMenu.saveLink();"/>
Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела
Отсутствует
в итоге получилось :
try { var url = "**************"; var request = new XMLHttpRequest(); request.open("HEAD", url, false); request.send(null); var responseHeaders = request.getResponseHeader("Content-Disposition"); }catch(e){}finally{responseHeaders;}
Работает. Но есть мнение, что это не есть хорошо, нужно как то так:
try { var url = "**************"; var request = new XMLHttpRequest(); var processReqChange = function() { try { if (request.readyState == 4 && request.status == 200) {var responseHeaders = request.getResponseHeader("Content-Disposition");} } catch(e) { } } ; request.onreadystatechange = processReqChange; request.open("HEAD", url, true); request.send(null); }catch(e){}finally{responseHeaders;}
Но не работает - возвращает пустую строку, хотя, судя по логам файервола, запрос на сервер проходит. Что то не так с возвратом или видимостью responseHeaders за пределами "processReqChange" ?
Отредактировано Iczer (06-10-2013 12:29:48)
Отсутствует
Страницы: 1