“Ajax upload” ანუ ფაილის ატვირთვა სერვერზე Ajax მიდგომით როგორც ასეთი მითია და სინამდვილეში არავითარი Ajax upload არ არსებობს გამომდინარე იქედან რომ ფაილის ატვირთვა სერვერზე სინამდვილეში არ ხდება XMLHttpRequest(XHR) ობიექტის გამოყენებით(და ეს შეუძლებელია ამ მომენტისათვის), ნაცვლად ამისა ამ ამოცანის გადასაჭრელად გამოიყენება დამალული iframe ელემენტი რაც ქმნის შესაბამის ილუზიას რომ ფაილის ატვირთვა ხდება ე.წ. “Ajax” მეთოდით.
დღესდღეობით ეს გამოსავალი ერთადერთია და რაც ყველაზე მნიშვნელოვანია იგი მუშაობს და მუშაობს ძალიან კარგად, თუმცა არსებობს ერთი დეტალი რომელიც საკმაოდ პრობლემატურია. პრობლემა მდგომარეობს სერვერიდან დაბრუნებულ პასუხში(response).
Ajax აპლიკაციის შექმნის ერთერთი აუცილებელი პირობაა სწორედ XHR ობიექტის გამოყენება. აღნიშნული ობიექტის მუშაობა არაფრით განსხვავდება ბრაუზერის მუშაობისგან, მისი მოვალეობაა სერვერზე მოთხოვნის გაგზავნა და შესაბამისად პასუხის მიღება. სერვერიდან დაბრუნებული პასუხი შეიძლება იყოს სამ ძირითად ფორმატში. ესენია:
- ჩვეულებრივ ტექსტი(plain text): ძირითადად გამოიყენება შედარებით მარტივ შემთხვევებში და სწრაფი რეზულტატის მისაღწევად;
- სწორად ფორმირებული XML დოკუმენტი: გამოიყენება სერვერიდან კომპლექსური პასუხების დასაბრუნებლად, პასუხი წარმოადგენს XHR ობიექტს responseXML თვისების მნიშვნელობას და იგი არის გამზადებული DOM ობიექტი რომელთან მუშაობაც თავისუფლად შესაძლებელია JavaScript – ის DOM მეთოდების მეშვეობით;
- Java Script Object Notation(JSON) ფორმატი: ასევე გამოიყენება კომპლექსურ შემთხვევებში და ეს ფორმატი წარმოადგენს გამზადებულ JavaScrip ობიექტს;
სამივე ჩამოთვლილ ფორმატს გააჩნია თავისი უპირატესობები და უარყოფითი მხარეები. XML და JSON ფორმატს შორის არჩევანი ალბათ უფრო გემოვნების საკითხია და უმარავი მომხრე და მოწინააღმდეგე ჰყავს ამ ორივე ფორმატს, მე პირადად XML ფორმატის გამოყენების მომხრე ვარ და მიდმივად ამ ფორმატით ვმუშაობ.
რაში გამოიხატება პრობლემა? როდესაც მოთხოვნა/პასუხი მთლიანად მუშავდება XHR ობიექტის გამოყენებით ყველაფერი ბუნებრივად და კარგად მუშაობს თუმცა როდესაც საჭიროა ისეთი HTML ფორმის გამოყენება რომლის მეშვეობითაც უნდა მოხდეს ფაილების ატვირთვა სერვერზე XHR გამოუყენებელი ხდება და იძულებული ვხდებით გამოვიყენოთ iframe ელემენტი. iframe – ს გამოყენების შემთხვევაში სერვერიდან პასუხი უნდა დაბრუნდეს HTML ფორმატში ნაცვლად ფორმირებული XML დოკუმენტისა, ეს აუცილებელია რადგან წინააღმდეგ შემთხვევაში ვერ შევძლებთ დაბრუნებული პასუხის კონტროლს(მე პირადად სხვა გზას ვერ მივაგენი). ჩამოტვირთული HTML დოკუმენტის გაკონტროლება კი ძალიან მარტივია, თუმცა აქ სხვა პრობლემას ვაწყდებით, კერძოდ კი HTML დოკუმენტში XML დოკუმენტის ჩაშენება არ შეიძლება(IE – ს გააჩნია მსგავსი შესაძლებლობა ე.წ. XML islands, მაგრამ სხვა ბრაუზერებში მსგავსი რამ არ მუშაობს). ერთადერთი გამოსავალია რომ სერვერიდან HTML – სთან ერთად დავაბრუნოთ XML დოკუმენტი მხოლოდ სტრიქონის სახით.
სტრიქონიდან XML დოკუმენტის მიღება
დავუშვათ XHR ობიექტის გამოყენების შემთხვევაში პასუხი სერვერიდან ბრუნდება მსგავსი XML დოკუმენტის სახით:
<response>
<item><![CDATA[This Is data]]></item>
</response>
ასეთ შემთხვევაში დაბრუნებული პასუხი გამზადებულ DOM ობიექტია და მასთან მუშაობა პირდაპირ შესაძლებელია შესაბამისი მეთოდების გამოყენებით. ხოლო iframe – ს გამოყენების შემთხვევაში სერვერიდან იგივე XML დოკუმენტის დაბრუნება გვიწევს შემდეგი სახით:
1 2 3 4 5 6 7 8 9 |
ეს არის ჩვეულებრივი HTML დოკუმენტი რომელსაც გააჩნია ერთი div ელემენტი იდენტიფიკატორით response. სწორედ მასშია მოთავსებული XML დოკუმენტი, თუმცა განსხვავებით ზემოთ ნაჩვენები XML დოკუმენტისგან მასში არსებული ტეგის გამხსნელი < და დამხური > სიმბოლოები გარდაქმნიალია შესაბამის < და > სიმბოლოებში რათა თავიდან ავიცილოთ გაუგებრობები.
ამ სტრიქონის წაკითხვა და გარდაქმნა შესაბამისად XML დოკუმენტში შესაძლებელია შემდეგი JavaScript – ის მეშვეობით:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* *put this code after "response" div */ //dom object var dom = null; //retrive string from "response" element var content = document.getElementById('response').innerHTML; //replace < and > back to <> symbols content = content.replace(/</gi, '<'); content = content.replace(/>/gi, '>'); //if current browser is IE ( :D ) if (window.ActiveXObject) { dom = new ActiveXObject("Microsoft.XMLDOM"); dom.async = false; dom.loadXML(content); } else { //all other browsers var parser = new DOMParser(); dom = parser.parseFromString(content, "text/xml"); } //read document element into response variable var response = dom.documentElement; //retrive first element from document and alert it's tag name alert(response.firstChild.tagName); |
ამ ჯავასკრიპტ კოდის ჩასმა(და დაბრუნება) შესაძლებელია ზემოთ ნაჩვნებ HTML დოკუმენტთან ერთად… მისი მუშაობის დეტალები მითითებულია კოდის კომენტარებში.
ეს მიდგომა კრიტიკულად მნიშვნელოვანია ისეთ შემთხვევებში როდესაც საჭიროა სერვერიდან მიღებული პასუხის დამუშავება ერთი სტანდარტული გზით, და იგი თავიდან გვაცილებს ყოველი ცალკეული შემთხვევებისათვის ახალი ე.წ. Response Processor – ების წერის აუცილებლობას.
ტეგები: Ajax, IE Sucks, JavaScript, JavaScript DOM
ძალიან საინტერესო სტატიაა, JSON ფორმატშიც როგორ ხდება ამის
დამუშავება კარგი იქნებოდა აღწერილი ყოფილიყო.
ჩემი აზრით JSON ფორმატი უფრო მისაღებია, რადგან რეალურად response-ის შედეგად მონაცემი ბრუნდება და თუ ის ობიექტად არის ფორმირებული თავისთვად ბუნებრივად ხდება მასთან მუშაობა,ხოლო XML-ის შემთხვევაში კიდე დამატებითი მანიპულაციები გჭირდება, რომ ამ ობიექტის ველების მნიშვნელობები წაიკითხო.
ვანო
თავისთავად JSON ცუდი არ არის, მაგრამ ჩემის აზრით მაინც არ არის იდეალური. კი ამბობენ რომ კითხვადობით არანაკლებია XML – ზეო და JSON გაცილებით სწრაფიაო მაგრამ სიმართლე გითხრა ვერც ერთი ვერ მივიღე 100% არგუმენტად… კითხვადობა აშკარად საკამათო საკითხია JSON – ში, სისწრაფე კი აშკარად არ იძლევა თვალშისაცემ შედეგს… თუმცა გვინდა თუ არ გვინდა Response Handler – ების წერა საჭიროა ორივე შემთხვევაში, ორივე შემთხვევაში გვიწევს რაღაც სტანდარტული ფორმატის ჩამოყალიბება და მისი დამუშავება, მაგრამ შედეგი საბოლოო ჯამში არ არის დიდად განსხვავებული. პირადად ჩემთვის XML მაინც ბევრად მისაღები ფორმატია თუმცა არც JSON – ის მოწინააღმდეგე ვარ.
ამ მაგალითში რაც დავწერე JSON – ის შემთხვევაში ბევრად მარტივი იქნებოდა ყველაფერი. სერვერიდან პასუხი ჩვეულებრივი ტექსტის (plain/text) სახით მოდის და eval ფუნქციის გამოყენება გვჭირდება რომ ტექსტისგან ჯავასკრიპტ ობიექტი მივიღოთ XHR – ს გამოვიყენებთ თუ დამალულ iFrame – ს არანაირი სხვაობა არ არის, სტრიქონი სტრიქონია
გამარჯობა.
ძალიან საინტერესო სტატიაა.
პრომლემა მაქვს ეხლა. მჩირდება გავაკეთო პროგრეს ბარი რომელიც ასახავს რამოდენიმე ფაილ-ფილდის ატვირთვის პროგრესს.
მოკლედ კითხვა მაქვს და თუ დამეხმარებით მადლობაელი დავრჩები
…
როდესაც მე ჩემი html ფაილიდან $_FILES მასივში მომდის ის ფაილი რომელიც უნდა ავტვირთო.
მე ამ დროს ვთქვათ move_upload_files() ფუნქციით ვტვირთავ ფიალს, პროგრესი როგორ ვნახო ან როგორ ავტვირთო ფაილი ისე რომ დამიბრუნოს პროგრესი?
კოკო
შეიძლება პროგრესის გაკეთება მაგრამ საკმაოდ არაბუნებრივი და რთული პროცესია… თუ აუცილებლად საჭიროა აპლოად პროგრესის ჩვენება ჩემის აზრით რაიმე მზა გადაწყვეტის გამოყენება ჯობია მაგალითად ეს http://swfupload.mammon.se/
სულაც არ არის პროგრეს ბარის გაკეთება ძნელი, ერთადერთი რაც ცოტა პრობლემატურია არის upload სიჩქარის დადგენა, მაგრამ ესეც მოგვარებადია