Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

HTML5 File Api, Java Script, UPLOAD fajla

[es] :: Javascript i AJAX :: HTML5 File Api, Java Script, UPLOAD fajla

[ Pregleda: 1090 | Odgovora: 1 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Mikelly

Član broj: 16730
Poruke: 389
*.crnagora.net.



Profil

icon HTML5 File Api, Java Script, UPLOAD fajla03.02.2012. u 15:51 - pre 148 meseci
Igram se sa ovim novim HTML5 File API-jem, i izgleda super, ali me izludje...

Ovako, pokusavam da napravim "kontrolu" za upload velikih fajlova iz chunkova sa progress bar-om.

Ideja je sledeca: kroz File Api citam fajl, cijepam ga u chunkove, postujem svaki ajax pozivom na server, posle svakog ajax posta saljem sledeci, osvjezim progres bar i to je to.

evo stranice:
Code:

<div>
    <label for="fileToUpload">Izaberite fajl za slanje</label><br />
    <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
</div>

<div>
    <input type="button" value="Upload" id="button1" />
</div>

<div>
<progress value="0" max="100" id="prg"/>
</div>


evo i javascript funkcija na stranici
Code:

$("#button1").click(function () {
    document.getElementById("prg").value = 0;
    send_file_chunk(-1, -1);
})

function send_file_chunk(start, end) {
    var file = document.getElementById("fileToUpload").files[0];
    var filesize = file.size;
    var done = "false";

    if (start == -1) start = 1; [red] Ne znam da li treba odje 0 ili 1, ali tek kad stavim 1 rekonstruisani fajl na kraju ima dobru velicinu, inace ima 1 byte vise. Ne mogu da nadjem na netu kako treba. [/red]
    if (end == -1) end = 50000; [red] Chunkovi su po 50 kb [/red]
    if (start + 50000 > filesize) { end = filesize; done = "true"; }

    var payload = file.mozSlice(start, end); [red] mozSlice() za mozzilu, webkitSlice() za chrome, ostali zasad nista.. [/red]
    var reader = new FileReader();
    reader.onloadend = function (evt) { if (evt.target.readyState == FileReader.DONE) { ActualSending(evt.target.result, file.name, start, end, filesize, done); } }  
    reader.readAsBinaryString(payload);
}

function ActualSending(payload, filename, start, end, size, done) {
    $.ajax({
        beforeSend: function (xhr) {
            xhr.setRequestHeader("Cache-Control", "no-cache");
            xhr.setRequestHeader("Start", start);
            xhr.setRequestHeader("Finish", end);
            xhr.setRequestHeader("Name", filename);
            xhr.setRequestHeader("Size", size);
            xhr.setRequestHeader("Done", done);
            xhr.setRequestHeader("Content-Type", "multipart/form-data");
        },
        type: 'POST',
        url: "/Home/Upload1",
        processData: false,
        data: payload,
        success: function (data, textStatus, xhr) { document.getElementById("prg").value = data[0] / size * 100; if (data[2] != "kraj") send_file_chunk(data[0], data[1]); },
        error: function (xhr, textStatus, errorThrown) { alert(errorThrown); }
    });
}


i na kraju ASP.NET MVC3 akcija koja se poziva ajax-om"
Code:

[HttpPost]
public JsonResult Upload1()
{
[red] Ovo su informacije za chunk koje embeddujem u request [/red]
int start = int.Parse(Request["HTTP_Start"]);
int finish = int.Parse(Request["HTTP_Finish"]);
int size = int.Parse(Request["HTTP_Size"]);
string filename = Request["HTTP_Name"];
string done = Request["HTTP_Done"];

System.IO.MemoryStream ms = new System.IO.MemoryStream();

int count = 0;
while(true)
{
    int b = Request.InputStream.ReadByte(); [red] Odje dobijam oko 75 kb stream iako je saljem chunk od 50 kb. Tako da su moji chunkovi uvijek oko 75 kb, ali se svaki ponaosob razlikuje za bar nekoliko bytova [/red]
    if (start + count++ > size) { done = "true"; break; } [red] Zadnji chunk, da ne procitam previse, jer je inputstream veci nego sto treba, ne znam sto drugo da radim... [/red]
    if (b == -1) break;
    ms.WriteByte((byte)b);
}

// sacuvati fajl chunk u bazu...

if(done == "true")
{
    //rekonstruisati kompletan fajl na osnovu chunkova iz baze..
}

[red] Informacije potrebne za sledeci chunk: pocetak sledeceg chunka je ~75kb a ne na definisanih 50kb, opet mu ja definisem da treba da bude 50kb ali cu opet dobit nekih 75 kb. [/red]
return Json(new object[] { start + fp.FilePartData.Length, start + fp.FilePartData.Length + 50000, done == "true" ? "kraj" : "nijekraj" });
}


Znaci, ovo donekle radi...

Fajl je rekonstruisan sa tacnim brojem bytova, ali .zip fajlovi i .mdb fajlovi nisu upotrebljivi, dok .txt i .doc jesu, vjerovatno trpe neke greske u bajtovima...

Nesto propustam, pa ako neko ima iskustva sa ovim ili kakvu ideju, molio bih pomoc.

Pozdrav.
 
Odgovor na temu

Mikelly

Član broj: 16730
Poruke: 389
*.crnagora.net.



Profil

icon Re: HTML5 File Api, Java Script, UPLOAD fajla04.02.2012. u 21:03 - pre 148 meseci
Provalio sam rjesenje.

Sto jednostavno kad moze komplikovano :)

Ne treba uopste da koristim FileReader, treba prosto ovako:

Code:

function send_file_chunk(start, end) {

    var file = document.getElementById("fileToUpload").files[0];
    var filesize = file.size;
    var done = "false";

    if (start == -1) start = 0;
    if (end == -1) end = 500000;

    if (start + 500000 > filesize) { end = filesize; done = "true"; }

    var payload = file.mozSlice(start, end);

    ActualSending(payload, file.name, start, end, filesize, done);
}


Pozdrav.

[Ovu poruku je menjao Mikelly dana 04.02.2012. u 22:27 GMT+1]
 
Odgovor na temu

[es] :: Javascript i AJAX :: HTML5 File Api, Java Script, UPLOAD fajla

[ Pregleda: 1090 | Odgovora: 1 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.