Import z pliku tekstowego w javascript

0

Pracuje nad tematem exportu i importu danych w formacie .txt. Właściwie to export mam już zrobiony w ten sposób ze jest funkcja wybierająca dane, które następnie zapisywane są w ten sposób na dysku:

var content = new Blob([tresc], { type: 'text/plain' });
var a = document.createElement('a');
a.download = 'export.txt';
a.href = window.URL.createObjectURL(content);
a.click();

Teraz chciałbym zrobić import danych... ale nie wiem w tym momencie jak zaimplementować rozwiązanie do wyboru pliku z którego będą odczytywane dane. Nie wiem jak to da się zrobić w js... czy jest coś podobnego (okno dialogowe) jak powyżej, tyle żeby była dostępna ścieżka/nazwa_pliku.txt - da się tak zrobić?

Czy są jakieś standardowe rozwiązania importu?

Z góry dzięki za pomoc!

0

Ja bym to zaliczył do tej części branży, gdzie się zbyt dużo oczekuje po frontendzie.
Dla mnie to typowy algorytm backendowy

0

@ZrobieDobrze: chyba nie dopisałem więc wyjaśniam... importowany plik ma będzie na kliencie, nie na serwerze i nie chce ładować importowanych plików na serwer tylko same dane.

0

@LukeJL: OK. za twoją poradą skopiowałem parę linijek i mam taki kod:

//const selectedFile = document.getElementById('FileUpload1-file').files[0];

const selectedFile ="file:///d:/tmp/export.txt";
var rawFile = new XMLHttpRequest();

rawFile.open("GET", selectedFile , true);
rawFile.onreadystatechange = function ()
{
    if(rawFile.readyState === 4)
    {
        if(rawFile.status === 200 || rawFile.status == 0)
        {
            var allText = rawFile.responseText;
            alert(allText);
        }
    }
}
rawFile.send(null);

pierwszą linijkę zakomentowałem bo działa - tzn wybiera mi obiekt file - ale o tym za chwile...
dalej próbuję odczytać plik, ale i tu się pojawiają schody... firefox mi raportuje naruszenie zasad bezpieczeństwa... i że nie może odczytać tego pliku.
(oczywiście plik jest we wskazanym miejscu). probowałem wskazać scieżkę + selectedFile.name (export.txt) ale wyniki był ten sam.
Wreszcie wpisałem ścieżkę na sztywno i ciągle ten sam komunikat o naruszeniu bezpieczeństwa.

Dalej nie ma co patrzeć bo na razie nie doszedłem :(

Czy mogę prosić o jakieś wskazówki....

2
bzc0fq napisał(a):

dalej próbuję odczytać plik, ale i tu się pojawiają schody... firefox mi raportuje naruszenie zasad bezpieczeństwa... i że nie może odczytać tego pliku.

Jak odpalasz plik? Jeśli otworzysz po prostu plik *.html z dysku, to nie będzie on w stanie czytać plików w ten sposób, musisz odpalić to na jakimś serwerze (tzn. nie musisz tego wgrywać na serwer, możesz postawić nawet lokalny serwer u siebie na kompie i wchodzić przez localhost)

No i "file:///d:/tmp/export.txt" też raczej nie zadziała.

Ogólnie to nie jest tak, że przeglądarka widzi wszystkie pliki na dysku. To użytkownik musi wybrać i tym samym dać dostęp.

var rawFile = new XMLHttpRequest();

Czemu XMLHttpRequest? Nie lepiej fetch?

No i z tego co pamiętam, to przy ładowaniu plików w ten sposób dostajesz od razu dane tego pliku i dostęp do bufora (choć dawno z tego nie korzystałem, a to trochę porąbane jest, zabawa z buforami, filereaderami, blobami itp. JS, ale z tego co widzę[1], to masz tam metody typu FileReader.readAsText( czy inne), więc ściąganie tych plików raczej w ogóle nie powinno być potrzebne (jeśli dobrze pamiętam?), bo to już masz z automatu.

No i jak potrzebny ci url (np. żeby przypisać do img src), to tu piszą jak go uzyskać: https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications#using_object_urls

[1] Tu jeszcze masz info: https://www.html5rocks.com/en/tutorials/file/dndfiles//

0

@LukeJL: Dobra, trochę poczytałem i zmieniłem kod na taki:

async function produktyImport_worker(){
	console.log('produktImport_worker');
		
	const selectedFile = document.getElementById('FileUpload1-file').files[0];

	let formData = new FormData();   
	
    formData.append("file", selectedFile);
    await fetch('php/produktyUpload.php', {
      method: "POST", 
      body: formData
    });    
    console.log('Koniec');
	
}

i testowy php:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_FILES['file'])) {

		include '../db_connection.php';

		$filename = $_FILES['file']['name'];		
		$location = "import/".$filename;		
		if ( move_uploaded_file($_FILES['file']['tmp_name'], $location) ) { 		  
          echo 'Success'; 
		} else { 
		  echo 'Failure'; 
		}
	}
}

Wybieranie pliku działa, i php jest wywoływany z js chyba OK... ale w katalogu import na serwerze nie generuje się żaden plik a w konsoli przeglądarki dostaje błąd:

POST https://xxx.xxx.xxx.x/php/produktyUpload.php [HTTP/1.0 500 Internal Server Error 10ms]

Czy ktoś mi może pomoc wyjaśnić w czym jest problem...?

1

@bzc0fq: Pierwotnie tak właśnie chciałem zrobić - dobrze zrozumiałeś, ale po zgłębieniu tematu myślę że lepszym rozwiązaniem będzie upload przez js/php i dalsza obróbka i usuniecie pliku już po stronie serwera.

0

OK... problem z apachem rozwiązany... spowodowany był złymi uprawnieniami na fs na serwerze... teraz mam inny problem i utknąłem.
nie działa mi funkcja move_uploaded_file($_FILES['file']['tmp_name'], $location)

Czy jest jakiś log żeby sprawdzić w czym jest problem?

0

Dobra, znalazłem w logach błąd failed to open stream: wskazujący na nazwe pliku tymczasowego w katalogu /tmp ($_FILES['file']['tmp_name']).
Jakieś pomysły co dalej z tym robić?

0

ok.. problem rozwiązany... katalog import jest widziany jako ../import a nie import.
taki mały problem :)

0

Potrzebuję jeszcze jednej rzeczy, mianowicie - przesłać do pliku php (php/produktyUpload.php) kilka zmiennych do dalszego przetwarzania.
Kombinuje tak...:

const usunDane = document.getElementById('cbxUsunDane').checked;
const nadpiszDane = document.getElementById('cbxNadpiszDane').checked;

formData.append("file", selectedFile);
formData.append("usunDane", usunDane);
formData.append("nadpiszDane", nadpiszDane);

   await fetch('php/produktyUpload.php', {
     method: "POST", 
     body: formData
   });

ale nie wiem jak później odczytać zmienne usunDane i nadpiszDane w tym php...
Próbowałem tak:

if ($_FILES['nadpiszDane']=="true") {
	error_log("UPDATE ", 3, "/var/www/html/errors.log");
} else {
	error_log("INSERT ", 3, "/var/www/html/errors.log");
}

Ale nie chce mi to działać.

Czy może mi ktoś podpowiedzieć jak to zrobić?

0

@bzc0fq: OK.. zmienne są dostępne pod $_POST :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1