Полезная информация

Mozilla Россия — свежие версии программ Mozilla, а также масса полезной информации по каждому продукту.

№127-09-2013 17:27:55

Iczer
Участник
 
Группа: Members
Зарегистрирован: 25-08-2007
Сообщений: 63
UA: Firefox 10.0

Исправить/дополнить скрипт загрузки

Помогите исправить/дополнить скрипт загрузки файла на предмет "самоопределения" имени загружаемого файла, помещения файла в стандартный менеджер загрузок 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);

Отсутствует

 

№229-09-2013 00:02:28

Iczer
Участник
 
Группа: Members
Зарегистрирован: 25-08-2007
Сообщений: 63
UA: Firefox 10.0

Re: Исправить/дополнить скрипт загрузки

Господа! Просветите - почему не работает замена слешей на двойные:

Выделить код

Код:

var PathtoFile="E:\Program\Files\12345678.910";
var PathtoFile=PathtoFile.replace(/\\/g,"\\");
alert(PathtoFile);

Отсутствует

 

№329-09-2013 06:07:03

Infocatcher
Not found
 
Группа: Extensions
Зарегистрирован: 24-05-2007
Сообщений: 4339
UA: Firefox 24.0

Re: Исправить/дополнить скрипт загрузки

Iczer пишет

почему не работает замена слешей на двойные

Потому что \ – экранирующий символ.

Выделить код

Код:

var PathtoFile="E:\Program\Files\12345678.910";
alert(PathtoFile);
Выделить код

Код:

alert("\\"); // \

Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела

Отсутствует

 

№429-09-2013 12:28:38

Iczer
Участник
 
Группа: Members
Зарегистрирован: 25-08-2007
Сообщений: 63
UA: Firefox 10.0

Re: Исправить/дополнить скрипт загрузки

Infocatcher пишет

Потому что \ – экранирующий символ.

но каким образом тогда получить строку как она есть - с одинарными слешами, чтобы потом сработала замена?

Выделить код

Код:

var PathtoFile="E:\Program\Files\12345678.910".replace(/\\/g,"\\\\");
    alert(PathtoFile);

ведь я её даже ввести не могу - получаю : "E:ProgramFiles12345678.910"

Отсутствует

 

№529-09-2013 15:35:40

Infocatcher
Not found
 
Группа: Extensions
Зарегистрирован: 24-05-2007
Сообщений: 4339
UA: Firefox 24.0

Re: Исправить/дополнить скрипт загрузки

Iczer пишет

но каким образом тогда получить строку как она есть - с одинарными слешами, чтобы потом сработала замена?

Выделить код

Код:

var PathtoFile="E:\\Program\\Files\\12345678.910";
alert(PathtoFile);

Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела

Отсутствует

 

№629-09-2013 19:46:28

Iczer
Участник
 
Группа: Members
Зарегистрирован: 25-08-2007
Сообщений: 63
UA: Firefox 10.0

Re: Исправить/дополнить скрипт загрузки

Понятно, просто я рассчитывал, что должна сработать конструкция наподобие :

Выделить код

Код:

var PathtoFile="\Q"+"E:\Program\Files\12345678.910"+"\E";
alert(PathtoFile);

но, очевидно, нет.

Но, со слешами проще, а вот как узнать имя загружаемого файла из ссылки типа:

Выделить код

Код:

var SourceUrl = "http://www.site.com/........downloadid=8888";
var fileName = ...   //

то есть, если волюнтаристски задать "file.ext", всё работает, но хотелось бы знать точно

Отсутствует

 

№730-09-2013 10:32:05

Infocatcher
Not found
 
Группа: Extensions
Зарегистрирован: 24-05-2007
Сообщений: 4339
UA: Firefox 24.0

Re: Исправить/дополнить скрипт загрузки

Iczer пишет

но хотелось бы знать точно

Придется отправить на сервер запрос, пример есть в chrome://browser/content/nsContextMenu.js:
nsContextMenu.prototype.saveLink() => this.saveHelper()

Или можно попробовать отправить HEAD-запрос и в конце проверить nsIChannel.URI.spec, пример: https://gist.github.com/Infocatcher/5327631 (в данном случае вполне хватит самой простой версии).


Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела

Отсутствует

 

№801-10-2013 23:05:10

Iczer
Участник
 
Группа: Members
Зарегистрирован: 25-08-2007
Сообщений: 63
UA: Firefox 10.0

Re: Исправить/дополнить скрипт загрузки

Infocatcher пишет

Придется отправить на сервер запрос, пример есть в 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);
  },

Отсутствует

 

№902-10-2013 08:14:24

Infocatcher
Not found
 
Группа: Extensions
Зарегистрирован: 24-05-2007
Сообщений: 4339
UA: Firefox 24.0

Re: Исправить/дополнить скрипт загрузки

Iczer пишет

Фунцию нашёл, но не никак не разберусь - на что указывает в данном случае "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();"/>

Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела

Отсутствует

 

№1006-10-2013 12:29:04

Iczer
Участник
 
Группа: Members
Зарегистрирован: 25-08-2007
Сообщений: 63
UA: Firefox 10.0

Re: Исправить/дополнить скрипт загрузки

в итоге получилось :

Выделить код

Код:

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)

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]