HTML5 et Javascript : Ouverture et la Lecture d'un Fichier Local avec un Fichier API
Je suis en utilisant Google Web Toolkit pour un projet et souhaitez que l'utilisateur de sélectionner un fichier texte pour l'ouvrir dans une fenêtre de texte à l'intérieur du navigateur. Voici la presque code de travail:
private DialogBox createUploadBox() {
final DialogBox uploadBox = new DialogBox();
VerticalPanel vpanel = new VerticalPanel();
String title = "Select a .gms file to open:";
final FileUpload upload = new FileUpload();
uploadBox.setText(title);
uploadBox.setWidget(vpanel);
HorizontalPanel buttons = new HorizontalPanel();
HorizontalPanel errorPane = new HorizontalPanel();
Button openButton = new Button( "Open", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
String filename = upload.getFilename();
int len = filename.length();
if (len < 5) {
Window.alert("Please enter a valid filename.\n\tFormat: <filename>.gms");
} else if (!filename.substring(len-4).toLowerCase().equals(".gms")) {
Window.alert(filename.substring(len-4) + " is not valid.\n\tOnly files of type .gms are allowed.");
} else {
Window.alert(getFileText(filename));
}
}
private native String getFileText(String filename) /*-{
//Check for the various File API support.
if (window.File && window.FileReader && window.FileList && window.Blob) {
//Great success! All the File APIs are supported.
var reader = new FileReader();
var file = File(filename);
str = reader.readAsText(file);
return str;
} else {
alert('The File APIs are not fully supported in this browser.');
return;
}
}-*/;
});
Button cancelButton = new Button( "Cancel",
new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
uploadBox.hide();
}
});
buttons.add(openButton);
buttons.add(cancelButton);
vpanel.add(upload);
vpanel.add(buttons);
vpanel.add(errorPane);
uploadBox.setAnimationEnabled(true);
uploadBox.setGlassEnabled(true);
uploadBox.center();
return uploadBox;
}
Chaque fois que j'essaie d'utiliser cette fonction dans mon programme, j'obtiens:
(NS_ERROR_DOM_SECURITY_ERR): erreur de Sécurité
Je suis certain qu'il est tubé par:
var file = new File(filename, null);
Avertissement: je ne suis pas un programmeur Javascript par un tronçon, n'hésitez pas à signaler toute erreur évidente, je suis en train de faire ici.
- re: les mises à jour - fenêtre/$wnd est probablement le seul point qui est gwt-spécifique. Qui, et comment passer dans le InputElement instance.
Vous devez vous connecter pour publier un commentaire.
Au lieu d'utiliser
window
, vous devriez toujours utiliser$wnd
. Voir https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsJSNI#writing pour plus de détails sur JSNI.Il pourrait également être intéressant d'ajouter un
debugger
déclaration tout en utilisant quelque chose comme Firebug ou Chrome, de l'Inspecteur. Cette déclaration va arrêter le code JS dans le débogueur comme si vous aviez mis un point d'arrêt, sont vous permettre de déboguer en Javascript, pas à pas, ligne par ligne pour voir exactement ce qui s'est passé.Et enfin, êtes-vous sûr que le fichier que vous lisez est autorisée par le navigateur? De http://dev.w3.org/2006/webapi/FileAPI/#dfn-SecurityError, cette erreur peut se produire parce que le navigateur n'a pas été autorisé à accéder au fichier. Au lieu de passer dans la Chaîne, vous pouvez passer dans le
<input type='file' />
l'utilisateur interagit avec, et obtenir le fichier sélectionné à partir de là.Mise à jour (désolé pour le retard, apparemment la mise à jour antérieure j'ai fait suis jeté à l'écart, m'a pris un peu de le réécrire):
Quelques mauvaises hypothèses soient formulées dans le code d'origine. La plupart de mes lectures est de http://www.html5rocks.com/en/tutorials/file/dndfiles/, en plus d'un peu d'expérimentation.
<input type='file' />
champ, couplé avecFileReader
API est synchrone.Pour des raisons de sécurité, la plupart des navigateurs ne donnent pas de véritables parcours quand vous lisez le nom du fichier - vérifier la chaîne que vous obtenez à partir
upload.getFilename()
dans plusieurs navigateurs pour voir ce que ça donne, pas assez pour charger le fichier. La deuxième question est également de sécurité, chose que très peu de bon ne peut venir de permettre la lecture à partir du système de fichiers en utilisant simplement une chaîne pour spécifier le fichier à lire.Pour ces deux premières raisons, vous devez demander à la
input
pour les fichiers c'est de travailler. Les navigateurs qui prennent en charge les FileReader API permettent d'accéder à cette par la lecture de lafiles
propriété de l'élément d'entrée. Deux façons simples pour obtenir ce travail avec la NativeElement.getEventTarget() dans jsni, ou simplement de travailler avec FileUpload.getElement(). Gardez à l'esprit que cefiles
propriété contient plusieurs éléments par défaut, de sorte que dans un cas comme le vôtre, il suffit de lire le zéro de l'élément.ou
Pour le dernier morceau, le
FileReader
api asynchrone - vous n'obtenez pas le contenu complet du fichier immédiatement, mais besoin d'attendre jusqu'à ce que leonloadend
callback n'est appelé (encore une fois, de http://www.html5rocks.com/en/tutorials/file/dndfiles/). Ces fichiers peuvent être assez grand pour que vous ne voudriez pas que l'application de bloquer pendant qu'il lit, donc, apparemment, la spec assume ce que la valeur par défaut.C'est pourquoi j'ai fini par faire une nouvelle
void loadContents
méthodes, au lieu de garder le code dans votreonClick
de la méthode cette méthode est appelée lorsque le champ estChangeEvent
s'en va, pour commencer à le lire dans le fichier, bien que cela puisse être écrit d'une autre façon.Le bouton 'Ok' puis se lit dans les champs. Il serait probablement plus sage de vérifier que le contenu est non null dans le
ClickHandler
, et peut-être même nulle quand laFileUpload
'sChangeEvent
s'éteint.var that = this;
réaffectation? Je peux penser de moi, mais je veux juste l'entendre de quelqu'un qui sait ce qu'ils font 🙂that=this
est pour leonloadend
de rappel -this
n'est pas vraiment la même chose en JS comme il est en Java, donc vous devez tenir compte du fait que, dans ce rappel,this
signifie ce que la fonction est appelée. Un rapide exemple suggère qu'il sera leFileReader
, mais dans de nombreux cas, les rappels sont invoqués avecwindow
(en gwt,$wnd
) comme lethis
.Aussi loin que je peux voir, vous ne pouvez utiliser
new File(name)
lors de l'écriture d'extensions: https://developer.mozilla.org/en/Extensions/Using_the_DOM_File_API_in_chrome_code