附錄二:免置頂上傳之運用

進入主題前要再次提醒,整份教學的編排都是循序漸進的!! 當你會有感覺到看的粉吃力時,極有可能是你已漏掉了先前某篇裏的某觀念了!!
所以請先確認實戰教學與附錄一的內容你都有瀏覽過了!! 那相信大家都粉期待這部份的教學,廢話就不多說,開始進入主題~
附錄二共分成三個部份:
第一部份在帶入原理的觀念~ (不想看的人可跳過這部份)
第二部份則是在講如何套用模組來生成GDL碼~ !!
這是寫免置頂上傳的基礎必修喔,裏面有兩個例子絕對務必要搞懂!!
附件: Get-Ajax-Data.GDL
第三部份則是精選四個範例 底下舉的這幾個例子比較不同於一般的回傳頁寫法,大家可參考看看

先來仔細看一下這篇教學的重點所在:檔案上傳欄位
如上,位於某表單中的某個 type=file 的INPUT控制項!! 其具唯讀的(安全性考量)的特性,所以我們無法直接賦值給它~
要能在web直接處理,唯一的方式便是用貼上(ctrl+v)的方式!! 但要用貼的就一定得要將焦點置於該格上!!
所以連帶也將影響到其它正在執行的工作,比如即時對談窗口(Msn)等…
大家可回憶一下之前學過的 SetFileValue 指令~
【03-網頁控制類】
SetFileValue 指令的執行流程:
程式置頂 --> 把焦點移至參數一的欄位名稱上 ---> 用sendkey 的方式把參數二填上 (即鍵盤的 ctrl+v)
---> 失焦
---> 比對參數一之值是否與參數二之值一樣 (若不符合則重新回到程式置頂繼續重覆)
----> 比對完成,將程序移往下一行
(以上是複習,看不懂的人請回頭去翻…)
好,既然那一格填不進去的話,那我們換個角度來思考:
若我們改從表單(FORM)下手的話,那是不是就可以不用去管那格填不填的上了,不是嗎!!
不知大家是否曾發現,筆者在介紹前面幾篇上傳時,都是先完成單個檔案的上傳後,再補上多帳號、多檔案的流程??
而現在我們的想法便是將 " 完成單個檔案的上傳" 轉換成
" 完成具檔案欄位表單的送出"
,再補上多帳號、多檔案的流程!!
那關於表單的送出,大家應該還記得在基礎必修2曾學過的模擬表單送出的PostData 指令吧!!
PostData:輸出串,參照頁,Content-Type
依參數值在WebBrowser中直接發送POST請求輸出串之定義為:Url-action?欄位名1=值&欄位名2=值&欄位名3=值…
參照頁為選擇性參數
Content-Type為選擇性參數,預設為"application/x-www-form-urlencoded"
這個指令就是利用post 的方法把表單中的所有欄位名與其值串加起來,再由Url-action 傳送出去~
比如下面這個表單好了,我要把 "C:\stock.txt"
填入檔案那格,檔案描述則填入 "股票檔"

若照上述的PostData 指令定義的話,要送出這個表單就應該會是如下的模樣!!
PostData:http://www.friendlyshare.de/cgi-bin/fileuploader.cgi
?
file=C:\stock.txt
& T1=股票檔 & Submit=送出 ,
http://www.friendlyshare.de/
,
multipart/form-data
其中,深綠色標記是指 Url-action 。草綠色標記是指所有的欄位名與其值串加 。粉紅色標記是指參照頁。最後的黃色標記是指 編碼模式~
看起來是粉完美,不過實際上問題確粉大~
因為這樣的送出,附檔的內容,即 stock.txt 並沒有被送出!!
再請大家回憶一下基礎必修2裏曾提過的,當表單俱檔案欄位時,其送出後在【PostData 清單】裏看到的內容會是如下圖~

大家可清楚看到,每個欄位間不再是以符號& 來串加!! 而是改用 "--"+"boundary 的值" 來作區隔!!
而且在PostData 清單裏,也只會列到 type=file 那個欄位為止,其後面的欄位通通不會列出~
這也是一個關鍵點,因為接著檔案欄位後面的,本來該是其值。但現在這個值,除了是 "檔案的絕對路徑"外,還要有它的"實體SIZE" ~
所以當然不可能會列出來呀!! 因為隨便一個5MB的檔要你要用二進位來表示,那就可以列到阿米巴星球去了嘛…

好,那就改由我來列給大家看看,完整的表單送出會是何種模樣!! (當然我的附檔是1k都不到的啦 ^^)
下面要分三個部份看:
最上面的紅色大框:指的是表頭資料,例如 表單送出方式、Url-action 、Content-Type、參照頁
等都是定義在此~
接著中間的綠色大框:即是該表單裏所有的欄位資料!! 其中以在表頭定義過的 "--" +"boundary" 來作
為欄位間的分隔,
結尾時則是用 "--" +"boundary"+"--" 來判定!!
而欄位屬性為file 那格,有特別不一樣的寫法,即是 name=欄位名稱 ;
filename=檔案本機絕對路徑,接著下一行是該檔案的型態,再下一行則是檔案實體內容~
最後一個藍色的大框:當表單送出完成後,SERVER那邊回傳給我們的訊息,把它存成HTM檔來看,就是一個上傳完成時的頁面啦~

所以,我們要做的就是模擬紅大框與綠大框的部份來傳送,再接收藍大框的資料,即是一個完整的表單傳送過程~
當然要搞定這個過程是相當麻煩的,不過沒關系!! 麻煩的事情就由筆者來解決,大家只要稍微了解運作的原理後,懂得如何去套用GDL來生成即可~

如上述原理篇所提到的,我們現在要做的是:
將 " 完成單個檔案的上傳" 轉換成
" 完成具檔案欄位表單的送出"
,再補上多帳號、多檔案的流程!!
而 完成單個檔案的上傳 就是指
取檔、把相關欄位填上值、上傳、偵錯!! 其中需要用到的指令幾乎都可由 DEBUG的指令自動生成來完成!!
現在
完成具檔案欄位表單的送出 則是利用筆者設計的一個專門用來分析網頁表單資料的GDL
來自動成生!!
=============================== Get-Ajax-Data.GDL
===================================
上傳表單(FORM)中,最多有七種TagName,我們只要取其中三種 INPUT、SELECT、TEXTAREA 就夠用了
1 . INPUT 裏面有十種屬性(type),我們只要其中六種就好
1-1 . text、hidden
1-2 . file
1-3 . radio
1-4 . checkbox
1-5 . submit
2 . SELECT
3 . TEXTAREA
強迫過濾條件I :頁面中多檔上傳陣列欄位,只取第一個
強迫過濾條件II:當 type=submit 之欄位其 value 非由"英數符字串(含空格)"所組成時,則略過不取
指定過濾條件為:不排除 INPUT(text、hidden) 無值之欄位
=====================================================================================
上面列的是這個GDL的設計方向,看看就好,不用鳥它~ 
我們趕緊來看第一個例子比較實際!!
例:要寫 http://www.friendlyshare.de
空間的免置頂上傳gdl ~
那我們就開始來執行 get-Ajax-data.gdl ,讓它為我們自動生成模擬表單送出的GDL碼~
首先,第一個對話框會問你,欲分析的網址~

那當然是填入看的到檔案欄位的那個網址 , 即
http://www.friendlyshare.de 囉!!
接著執行窗會跳到剛才輸入的網址後,再出現第二個對話框告訴你,把該網頁上該處理的欄位都處理一下!!

這個意思就是說,叫你把頁面中 該填、該拉、該勾等
上傳必需選項 都手動設定好(上傳欄位不用管它)~
比如這個空間上傳必需選項就只有一個檔案欄位而已,所以我們不鳥它,直接按下【往下執行】鈕即可~
接著會馬上再跳出第三個對話框來問你是否要排除 INPUT
控制項裏無值之欄位。

這個意思是說,你在網頁中會看到某些選擇性的項目讓你填或不填!!
像這種的欄位,在SERVER那邊都不會檢驗,所以我們取欄位時就可以把那些沒填的欄位給省略掉~
像這空間我就直接按【確定】了!! ( 它完全沒格子可以填XD)
接下來就一直等到整個GDL跑完了!!
然後切換到【輸出清單】,把整個結果抄下來,如下!!
//------ 檔案上傳 by Ajax
Label:GetFile
GetFile()
IFNo:end
Label:up-page
go:about:blank
sleep()
AddWebHtml:<textarea name="FilePath" rows="1"
cols="40">***File***</textarea><p align="left"><span id="waitup"><img border=0
src="http://blog.xuite.net/_image/upload.gif" width="200" height="200"
></span></p>
sleep()
FindWebText:***File***
IFNO:up-page
RunScriptNext:var formDate = '--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="file"; filename="冏1"'+'\r\n'+'Content-Transfer-Encoding:
binary'+'\r\n'+'\r\n'+'{!--file--}'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="Submit"'+'\r\n'+'\r\n'+'Submit Form'+'\r\n'+'--AaB03x--'
RunScriptNext:formDate=formDate.replace('冏1',document.all('FilePath').value);
//RunScriptNext:formDate=formDate.replace('冏?','***Variable?***');
//若有"冏2"、"冏3"等需即時獲取的欄位值,就用上行方式加入即可
//RunScriptNext:alert(formDate)
RunScriptNext:function UniCodeToString(source) {var codeAry =
source.split("\/u");var sret = "";for(var i=0; i < codeAry.length; i++)
{if(codeAry[i]=="") continue;sret += String.fromCharCode("0x" + codeAry[i]);}
return sret; }
RunScriptNext:function strToChar(stream,charset){var str =""; var Stream = new
ActiveXObject("ADODB.Stream");Stream.Type = 1;Stream.Mode = 3; Stream.Open();
Stream.Write(stream);Stream.Position = 0;Stream.Type = 2; Stream.Charset =
charset ; str = Stream.ReadText(); Stream.Close(); Stream = null; return str;
}
RunScriptNext:function strToHex(str) { if ('' != str) { var st, t, i;st =
'';for (i = 1; i <= str.length; i ++){t = str.charCodeAt(i -
1).toString(16);if (t.length < 2) t = '0'.concat(t); st =
st.concat(t);}return(st.toUpperCase());} else {return('');}}
RunScriptNext:function loadFile(path) {stream = new
ActiveXObject("ADODB.Stream");stream.Type =
1;stream.Open();stream.LoadFromFile(path); binaryStream =
stream.Read();stream.close();stream=null;return binaryStream}
RunScriptNext:function byteToHex(byteStr) {var xmldom = new
ActiveXObject("Microsoft.XMLDOM");var byteObj=
xmldom.createElement("byteObj");byteObj.dataType =
'bin.hex';byteObj.nodeTypedValue = byteStr;return(String(byteObj.text));}
RunScriptNext:function hexToByte(hexStr) {var xmldom = new
ActiveXObject("Microsoft.XMLDOM");var byteObj=
xmldom.createElement("byteObj");byteObj.dataType =
"bin.hex";byteObj.nodeTypedValue = hexStr;return(byteObj.nodeTypedValue);}
RunScriptNext:sendbinary = hexToByte(
strToHex(formDate.split("{!--file--}")[0]) +
byteToHex(loadFile(document.all('FilePath').value)) +
strToHex(formDate.split("{!--file--}")[1]) );delete
binaryStream;CollectGarbage();
RunScriptNext:function loadHttpXML(post_action, sendObj , key_value) {var
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");xmlhttp.onreadystatechange =
xmlhttpReadychange;xmlhttp.open("POST", post_action,
true);xmlhttp.setRequestHeader("content-type", "multipart/form-data;
boundary=AaB03x");xmlhttp.send(sendObj);function xmlhttpReadychange(){if
(xmlhttp.readyState == 4){ var charresult =
xmlhttp.responseText.match(/CharSet=(\S+)\">/i); if(charresult == null
||charresult[1].toUpperCase() =='UTF-8') {var go=xmlhttp.responseText;}
else{var go =strToChar(xmlhttp.responseBody,charresult[1]);str=null;} ;
xmlhttp=null; if(UniCodeToString(key_value).length >1 ){var
key1=UniCodeToString(key_value)} else {key1=key_value}
;if(go.search(key1)!=-1) {document.all('FilePath').value='搞定'+go;} else
{document.all('FilePath').value='上傳失敗!!'+go;} ; }}}
RunScriptNext:loadHttpXML('http://www.friendlyshare.de/cgi-bin/fileuploader.cgi',
sendbinary , '上傳成功後頁面會顯示之字串(可用原始碼),字串也可用Unicode跳脫序列來表示'
)
sleep()
RunScriptNext:delete sendbinary;CollectGarbage();xmldom=null;
//--- 等待上傳結果的偵錯設計
Label:wait-up
WaitWebText:搞定,7,wait-up2
GoLabel:up-ok
Label:wait-up2
WaitWebText:上傳失敗,1,wait-up
GoLabel:up-page
Label:up-ok
ItemToVariable:FilePath,***Variable?***
利用 GetstrToVariable 等指令,把我們要的連結(資訊)從 ***Variable?*** 中取出
.......
.......
FileLoop:GetFile
.......
.......
Label:end
go:about:blank
<<所有檔案已上傳完畢>>
EXIT()
上面像天書般的內容,你不用去理解它!! 你只要依空間特性去更改我標記出來的四個部份即可~
先看粉紅標記:
這個地方指的是當空間有不固定之欄位值時,你必需
即時去取得資料來代入我們模擬的表單資料中
比如相片空間常會有隱藏的欄位值是代表 帳號ID、相本ID !! 所以當你多帳號上傳時,那些欄位就會有不同的值, 我們必需即時去取得再代入模擬的表單資料中!!
再來看綠色標記:這地方就是放上傳表單的 Action 值 !!
也就是我們上傳用的Url_Action ~
有時它也是不固定的,會帶有一個參數值!! 或是它可以是多主機別的,我們可以自行指定運用~
接著是黃色標記:這個地方就是填入上傳成功時會出現的字串(可以是網頁源始碼)
其中當你的偵錯字串不屬中英數字時(比如泡菜字 업 로드하는 것에 성공합니다 ),則可用Unicode跳脫序列來表示(
不懂的往前翻實單教學)
最後是灰色標記:這裏是確認上傳成功後,由SERVER端回傳的頁面,將會
以源始碼的型態放入我們自已架設的格子(
FilePath) 中
預設將把回傳頁的源始碼存入一個自定變數?裏,接著我們便可利用 GetstrToVariable 指令來從中獲取需要的資訊~
以http://www.friendlyshare.de
空間而言,並沒有不固定之欄位值(粉紅標記處)! 表單的action 值也是固定的(綠色標記處)
所以我們第一個改的地方是黃色標記住,即 "檔案上傳成功後的字眼" !!

上圖為我手動上傳一個小檔成功後的頁面。所以我選擇取 "having uploaded your" 作為上傳是否成功的關鍵字!!
黃色標記則應改成如下所示~
RunScriptNext:loadHttpXML('http://www.friendlyshare.de/cgi-bin/fileuploader.cgi',
sendbinary , 'having uploaded your' )
那再來第二個要改的地方便是灰色標記處 !! 也就是從回傳頁來取得我們需要的資訊,比如檔案連結~
你可以把自定變數?的值貼到網頁編輯軟體裏去看,就會發現它與我們用正常方式上傳完的回傳頁是一模一樣的!! 只是多了個我們預設上傳成功時加上的文字 "搞定"
!!

那本來若我們用原來的方式上傳,上傳成功後會用WebStrToVariable: 指令來取網頁中的字串!! (用NT的檢視原始檔來找參數)
【03-網頁控制類 】
但現在上傳成功後的那個頁面,已被我們存入自定變數?中了!! 所以我們就改用 GetstrToVariable 指令來取得變數?中的某值!!
【03-網頁控制類 】
( GetstrToVariable 的參數要如何下應該不用我教吧 !!)
所以灰色標記的部份我會改用如下所示~
Label:up-ok
ItemToVariable:FilePath,***Variable57***
GetstrToVariable:***Variable57***,http://www.friendlyshare.de/files/,",***Variable2***
output:http://www.friendlyshare.de/files/***Variable2***
最後再把多檔案的程序補上~
Label:up-ok
ItemToVariable:FilePath,***Variable57***
GetstrToVariable:***Variable57***,http://www.friendlyshare.de/files/,",***Variable2***
output:http://www.friendlyshare.de/files/***Variable2***
FileLoop:GetFile
Label:end
go:about:blank
output:<<所有檔案已上傳完畢>>
EXIT()
到此,一個免置頂的上傳GDL 就完成了… 看起來像天書般的東西,就只要改兩個地方而已,有夠給它容易吧!!

//------ 檔案上傳 by Ajax
Label:GetFile
GetFile()
IFNo:end
Label:up-page
go:about:blank
sleep()
AddWebHtml:<textarea name="FilePath" rows="1"
cols="40">***File***</textarea><p align="left"><span id="waitup"><img border=0
src="http://blog.xuite.net/_image/upload.gif" width="200" height="200"
></span></p>
sleep()
FindWebText:***File***
IFNO:up-page
RunScriptNext:var formDate = '--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="file"; filename="冏1"'+'\r\n'+'Content-Transfer-Encoding:
binary'+'\r\n'+'\r\n'+'{!--file--}'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="Submit"'+'\r\n'+'\r\n'+'Submit Form'+'\r\n'+'--AaB03x--'
RunScriptNext:formDate=formDate.replace('冏1',document.all('FilePath').value);
//RunScriptNext:formDate=formDate.replace('冏?','***Variable?***');
//若有"冏2"、"冏3"等需即時獲取的欄位值,就用上行方式加入即可
//RunScriptNext:alert(formDate)
RunScriptNext:function UniCodeToString(source) {var codeAry =
source.split("\/u");var sret = "";for(var i=0; i < codeAry.length; i++)
{if(codeAry[i]=="") continue;sret += String.fromCharCode("0x" + codeAry[i]);}
return sret; }
RunScriptNext:function strToChar(stream,charset){var str =""; var Stream = new
ActiveXObject("ADODB.Stream");Stream.Type = 1;Stream.Mode = 3; Stream.Open();
Stream.Write(stream);Stream.Position = 0;Stream.Type = 2; Stream.Charset =
charset ; str = Stream.ReadText(); Stream.Close(); Stream = null; return str;
}
RunScriptNext:function strToHex(str) { if ('' != str) { var st, t, i;st =
'';for (i = 1; i <= str.length; i ++){t = str.charCodeAt(i -
1).toString(16);if (t.length < 2) t = '0'.concat(t); st =
st.concat(t);}return(st.toUpperCase());} else {return('');}}
RunScriptNext:function loadFile(path) {stream = new ActiveXObject("ADODB.Stream");stream.Type
= 1;stream.Open();stream.LoadFromFile(path); binaryStream =
stream.Read();stream.close();stream=null;return binaryStream}
RunScriptNext:function byteToHex(byteStr) {var xmldom = new
ActiveXObject("Microsoft.XMLDOM");var byteObj=
xmldom.createElement("byteObj");byteObj.dataType = 'bin.hex';byteObj.nodeTypedValue
= byteStr;return(String(byteObj.text));}
RunScriptNext:function hexToByte(hexStr) {var xmldom = new
ActiveXObject("Microsoft.XMLDOM");var byteObj=
xmldom.createElement("byteObj");byteObj.dataType =
"bin.hex";byteObj.nodeTypedValue = hexStr;return(byteObj.nodeTypedValue);}
RunScriptNext:sendbinary = hexToByte(
strToHex(formDate.split("{!--file--}")[0]) +
byteToHex(loadFile(document.all('FilePath').value)) +
strToHex(formDate.split("{!--file--}")[1]) );delete
binaryStream;CollectGarbage();
RunScriptNext:function loadHttpXML(post_action, sendObj , key_value) {var
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");xmlhttp.onreadystatechange =
xmlhttpReadychange;xmlhttp.open("POST", post_action, true);xmlhttp.setRequestHeader("content-type",
"multipart/form-data; boundary=AaB03x");xmlhttp.send(sendObj);function
xmlhttpReadychange(){if (xmlhttp.readyState == 4){ var charresult =
xmlhttp.responseText.match(/CharSet=(\S+)\">/i); if(charresult == null
||charresult[1].toUpperCase() =='UTF-8') {var go=xmlhttp.responseText;}
else{var go =strToChar(xmlhttp.responseBody,charresult[1]);str=null;} ;
xmlhttp=null; if(UniCodeToString(key_value).length >1 ){var
key1=UniCodeToString(key_value)} else {key1=key_value}
;if(go.search(key1)!=-1) {document.all('FilePath').value='搞定'+go;} else
{document.all('FilePath').value='上傳失敗!!'+go;} ; }}}
RunScriptNext:loadHttpXML('http://www.friendlyshare.de/cgi-bin/fileuploader.cgi',
sendbinary , 'having uploaded your')
sleep()
RunScriptNext:delete sendbinary;CollectGarbage();xmldom=null;
//--- 等待上傳結果的偵錯設計
Label:wait-up
WaitWebText:搞定,7,wait-up2
GoLabel:up-ok
Label:wait-up2
WaitWebText:上傳失敗,1,wait-up
GoLabel:up-page
Label:up-ok
ItemToVariable:FilePath,***Variable57***
GetstrToVariable:***Variable57***,http://www.friendlyshare.de/files/,",***Variable2***
output:http://www.friendlyshare.de/files/***Variable2***
FileLoop:GetFile
Label:end
go:about:blank
output:<<所有檔案已上傳完畢>>
EXIT()
好,那接著來看一下使用限制!!!
首先, 因為有讀取本機的檔案,所以
安全性的問題一樣存在!! 這個無法避免,只能透過設定來解決!! ( 底下的設定適用於 IE 6、7 )
// -----★安全性設定★
// -----★
1.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 網站
【將 about:blank 填入後,按新增,再按確定!】(此區域內的所有網站需要伺服器驗証 別打勾)
// -----★ 2.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【起始不標示為安全的ActiveX控制項,請改為"啟用"】
// -----★ 3.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【存取各(跨)網域的資料來源,請改為"啟用"】
// -----★ 4.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【在較少特殊權限的網頁內容區域中的網站可以瀏覽,請改為"啟用"】(非必要選項
)
這裏以IE7 為例子,附上 免置頂上傳模組的設定圖解說明,供大家參考。(按我開啟)
再來是
檔案名稱與其所在路徑 不得包含中文!!
( 原理要說到你懂又得另開一篇來解釋了,所以略過…
)
接著是
上傳檔案大小的限制!!
因為這種方式是模擬整個表單的資料送出,所以資料裏自然也會包括了上傳檔案的實體SIZE !! (詳參原理篇)
比如單檔是10MB的話,那在有1G記憶體中的PC來處理資料建立的過程,可能就需要花到100MB ~
而若只有512MB的話,可能只需花60MB 來處理,但是相對處理時間會比有1G的PC多花費許多時間~
所以單檔大小限制是以不影響你本機工作為準來調整的~
建議可先從10MB的檔案測起,再逐步加大、減少,以找出最適合你PC環境的單檔限制~
( 以筆者 P4_3G、 1G RAM 來說,在不影響到OS中其它的工作的前提下,單檔50MB 就差不多是MAX 了 )
另外,記得每次上傳前都要新開一次NT, 以確保上傳前PC的內存是清空狀態下的~
那,我們就再把重點提示與此GDL的相關訊息加上去,就是一個標準又完整的 免置頂上傳GDL 囉 !!

//-----名
稱:friendlyshare.de(up)_Ajax.gdl
//-----編寫日期:2007-01-23 by 我愛小美
//-----編寫環境:NetTools v1.5 & win2k_sp4
//-----最後修正:
// -----★安全性設定★
// -----★
1.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 網站 【將 about:blank
填入後,按新增,再按確定!】(此區域內的所有網站需要伺服器驗証 別打勾)
// -----★ 2.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【起始不標示為安全的ActiveX控制項,請改為"啟用"】
// -----★ 3.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【存取各(跨)網域的資料來源,請改為"啟用"】
// -----★ 4.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【在較少特殊權限的網頁內容區域中的網站可以瀏覽,請改為"啟用"】(非必要選項
)
// -----★ 每次執行上傳前,請把NT重開一次,以確保內存是清空狀態下的
// -----★ 上傳檔案之絕對路徑不得有中文字!!
// -----★ 強烈建議 MAX 20MB per file. (可視個人配備調整)
//------ 檔案上傳 by Ajax
Label:GetFile
GetFile()
IFNo:end
Label:up-page
go:about:blank
sleep()
AddWebHtml:<textarea name="FilePath" rows="1" cols="40">***File***</textarea><p
align="left"><span id="waitup"><img border=0 src="http://blog.xuite.net/_image/upload.gif"
width="200" height="200" ></span></p>
sleep()
FindWebText:***File***
IFNO:up-page
RunScriptNext:var formDate = '--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="file"; filename="冏1"'+'\r\n'+'Content-Transfer-Encoding:
binary'+'\r\n'+'\r\n'+'{!--file--}'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="Submit"'+'\r\n'+'\r\n'+'Submit Form'+'\r\n'+'--AaB03x--'
RunScriptNext:formDate=formDate.replace('冏1',document.all('FilePath').value);
//RunScriptNext:formDate=formDate.replace('冏?','***Variable?***');
//若有"冏2"、"冏3"等需即時獲取的欄位值,就用上行方式加入即可
//RunScriptNext:alert(formDate)
RunScriptNext:function UniCodeToString(source) {var codeAry = source.split("\/u");var
sret = "";for(var i=0; i < codeAry.length; i++) {if(codeAry[i]=="")
continue;sret += String.fromCharCode("0x" + codeAry[i]);} return sret; }
RunScriptNext:function strToChar(stream,charset){var str =""; var Stream = new
ActiveXObject("ADODB.Stream");Stream.Type = 1;Stream.Mode = 3; Stream.Open();
Stream.Write(stream);Stream.Position = 0;Stream.Type = 2; Stream.Charset =
charset ; str = Stream.ReadText(); Stream.Close(); Stream = null; return str;
}
RunScriptNext:function strToHex(str) { if ('' != str) { var st, t, i;st =
'';for (i = 1; i <= str.length; i ++){t = str.charCodeAt(i -
1).toString(16);if (t.length < 2) t = '0'.concat(t); st =
st.concat(t);}return(st.toUpperCase());} else {return('');}}
RunScriptNext:function loadFile(path) {stream = new
ActiveXObject("ADODB.Stream");stream.Type = 1;stream.Open();stream.LoadFromFile(path);
binaryStream = stream.Read();stream.close();stream=null;return binaryStream}
RunScriptNext:function byteToHex(byteStr) {var xmldom = new
ActiveXObject("Microsoft.XMLDOM");var byteObj=
xmldom.createElement("byteObj");byteObj.dataType = 'bin.hex';byteObj.nodeTypedValue
= byteStr;return(String(byteObj.text));}
RunScriptNext:function hexToByte(hexStr) {var xmldom = new
ActiveXObject("Microsoft.XMLDOM");var byteObj=
xmldom.createElement("byteObj");byteObj.dataType = "bin.hex";byteObj.nodeTypedValue
= hexStr;return(byteObj.nodeTypedValue);}
RunScriptNext:sendbinary = hexToByte( strToHex(formDate.split("{!--file--}")[0])
+ byteToHex(loadFile(document.all('FilePath').value)) +
strToHex(formDate.split("{!--file--}")[1]) );delete
binaryStream;CollectGarbage();
RunScriptNext:function loadHttpXML(post_action, sendObj , key_value) {var
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");xmlhttp.onreadystatechange =
xmlhttpReadychange;xmlhttp.open("POST", post_action,
true);xmlhttp.setRequestHeader("content-type", "multipart/form-data;
boundary=AaB03x");xmlhttp.send(sendObj);function xmlhttpReadychange(){if (xmlhttp.readyState
== 4){ var charresult = xmlhttp.responseText.match(/CharSet=(\S+)\">/i);
if(charresult == null ||charresult[1].toUpperCase() =='UTF-8') {var go=xmlhttp.responseText;}
else{var go =strToChar(xmlhttp.responseBody,charresult[1]);str=null;} ;
xmlhttp=null; if(UniCodeToString(key_value).length >1 ){var key1=UniCodeToString(key_value)}
else {key1=key_value} ;if(go.search(key1)!=-1) {document.all('FilePath').value='搞定'+go;}
else {document.all('FilePath').value='上傳失敗!!'+go;} ; }}}
RunScriptNext:loadHttpXML('http://www.friendlyshare.de/cgi-bin/fileuploader.cgi',
sendbinary , 'having uploaded your')
sleep()
RunScriptNext:delete sendbinary;CollectGarbage();xmldom=null;
//--- 等待上傳結果的偵錯設計
Label:wait-up
WaitWebText:搞定,7,wait-up2
GoLabel:up-ok
Label:wait-up2
WaitWebText:上傳失敗,1,wait-up
GoLabel:up-page
Label:up-ok
ItemToVariable:FilePath,***Variable57***
GetstrToVariable:***Variable57***,http://www.friendlyshare.de/files/,",***Variable2***
output:http://www.friendlyshare.de/files/***Variable2***
FileLoop:GetFile
Label:end
go:about:blank
output:<<所有檔案已上傳完畢>>
EXIT()
打鐵趁熱,接著再繼續看第二個例子: http://www.turboupload.com/
一樣是執行 get-Ajax-data.gdl ,讓它為我們自動生成模擬表單送出的GDL碼~
第一個框填入 http://www.turboupload.com/
第二個框是提醒我們把網頁中需要處理的欄位給弄好~
如下圖所示,選填的項目保持空白就好。主要把那個檔案描述與同意選核取的checkbox 給弄好就行了~

再來第三個框,因為剛才我們那個選填的都沒理它,所以現在當然是要排除掉它囉…
那就直接按【確定鈕】就好了~

接著便等GDL 跑完後,去【輸出清單】裏,把生成的資料COPY出來~
如下,我把中間部份略掉沒列出,因為那裏也沒影響。才不會看的落落長…
//------ 檔案上傳 by Ajax
Label:GetFile
GetFile()
IFNo:end
Label:up-page
go:about:blank
sleep()
AddWebHtml:<textarea name="FilePath" rows="1"
cols="40">***File***</textarea><p align="left"><span id="waitup"><img border=0
src="http://blog.xuite.net/_image/upload.gif" width="200" height="200"
></span></p>
sleep()
FindWebText:***File***
IFNO:up-page
RunScriptNext:var formDate = '--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="uploadp_id"'+'\r\n'+'\r\n'+'153665592.1175868084'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="filetoupload";
filename="冏1"'+'\r\n'+'Content-Transfer-Encoding:
binary'+'\r\n'+'\r\n'+'{!--file--}'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="description"'+'\r\n'+'\r\n'+'UP BY
KEYOUT'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition: form-data;
name="terms"'+'\r\n'+'\r\n'+'checkbox'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="Submit"'+'\r\n'+'\r\n'+'Upload File'+'\r\n'+'--AaB03x--'
RunScriptNext:formDate=formDate.replace('冏1',document.all('FilePath').value);
//RunScriptNext:formDate=formDate.replace('冏?','***Variable?***');
//若有"冏2"、"冏3"等需即時獲取的欄位值,就用上行方式加入即可
//RunScriptNext:alert(formDate)
.........................................................................
中間部份我把它略掉,才不會太長
.........................................................................
RunScriptNext:loadHttpXML('http://s17.turboupload.com/upload.tu?uploadp_id=153665592.1175868084',
sendbinary , '上傳成功後頁面會顯示之字串(可用原始碼),字串也可用Unicode跳脫序列來表示' )
sleep()
RunScriptNext:delete sendbinary;CollectGarbage();xmldom=null;
//--- 等待上傳結果的偵錯設計
Label:wait-up
WaitWebText:搞定,7,wait-up2
GoLabel:up-ok
Label:wait-up2
WaitWebText:上傳失敗,1,wait-up
GoLabel:up-page
Label:up-ok
ItemToVariable:FilePath,***Variable?***
利用 GetstrToVariable 等指令,把我們要的連結(資訊)從 ***Variable?*** 中取出
.......
.......
FileLoop:GetFile
.......
.......
.......
Label:end
go:about:blank
output:<<所有檔案已上傳完畢>>
EXIT()
那這個例子就比較有意思一點了!! 不過一樣是 依空間特性去更改我標記出來的四個部份即可~
先看黃色標記:這個地方指的是當空間有不固定之欄位值時,你必需即時去取得資料來代入我們模擬的表單資料中
uploadp_id
這個欄位值是非固定的!! 它該是與後面草綠色標出來的Post_Action 相關連的,每次頁面開啟都會不一樣~
所以我們會利用下面的方式來即時取得該值~
go:http://www.turboupload.com/
ItemToVariable:uploadp_id,***Variable2***

再來就是那個檔案描述的部份 !! 若你不想每次都填一樣的,那就來隨機生成吧!!
例如我可以弄個如右的格式: UP BY
隨機英文姓名 (現在時刻)
CreateEngName:***Variable3***,***Variable4***
SetDataValue:UP BY ***Variable3*** (***Time***),***Variable5***
所以黃標的部份就會變成如下:
把本來字串裏的兩個固定值,改用 冏2 、冏3 。然後就可以利用兩個對應的變數來即時改變它!!
RunScriptNext:var formDate = '--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="uploadp_id"'+'\r\n'+'\r\n'+'冏2'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="filetoupload";
filename="冏1"'+'\r\n'+'Content-Transfer-Encoding:
binary'+'\r\n'+'\r\n'+'{!--file--}'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="description"'+'\r\n'+'\r\n'+'冏3'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition: form-data;
name="terms"'+'\r\n'+'\r\n'+'checkbox'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="Submit"'+'\r\n'+'\r\n'+'Upload File'+'\r\n'+'--AaB03x--'
RunScriptNext:formDate=formDate.replace('冏1',document.all('FilePath').value);
RunScriptNext:formDate=formDate.replace('冏2','***Variable2***');
RunScriptNext:formDate=formDate.replace('冏3','***Variable5***');
//RunScriptNext:formDate=formDate.replace('冏?','***Variable?***');
//若有"冏2"、"冏3"等需即時獲取的欄位值,就用上行方式加入即可
再來看綠色標記:這地方就是放上傳表單的 Action 值 !!
也就是我們上傳用的Url_Action ~
這裏粉明顯看出它是不固定的,因為帶有一個參數叫 uploadp_id 的值!! 而且前面的 s17 似乎意謂著有多主機可指定!! 所以我們也必需即時
來取得~
WebStrToVariable:action=, method=post,***Variable6***
所以綠標的部份就會變成如下:
把本來的固定值,改用自定變數6來代替~
RunScriptNext:loadHttpXML('***Variable6***',
sendbinary , '上傳成功後頁面會顯示之字串(可用原始碼),字串也可用Unicode跳脫序列來表示' )
接著是灰色標記:這個地方就是填入上傳成功時會出現的字串(可以是網頁源始碼)

一樣先手動傳個小檔再來挑成功的字眼,比如這裏我就選擇 successfully uploaded 來作為判斷是否上傳成功的關鍵字!!
那灰色標記的部份就會變成如下:
RunScriptNext:loadHttpXML('***Variable6***',
sendbinary , 'successfully uploaded' )
最後是X色標記:這裏是確認上傳成功後,由SERVER端回傳的頁面,其會以源始碼的型態放入我們自已架設的格子(
FilePath) 中
我就先把那一格的值存入自定變數24中,然後再取出我要的下載連結~
Label:up-ok
ItemToVariable:FilePath,***Variable24***
GetstrToVariable:***Variable24***,Download-Link</strong>: <a
href=",",***Variable10***
output:***Variable10***
完成四個標記處後,再把多檔的程序補上,就是下面這個完整的免置頂上傳GDL囉~
//-----名 稱:turboupload.de(up)_Ajax.gdl
//-----編寫日期:2007-01-23 by 我愛小美
//-----編寫環境:NetTools v1.5 & win2k_sp4
//-----最後修正:
// -----★安全性設定★
// -----★
1.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 網站
【將 about:blank 填入後,按新增,再按確定!】(此區域內的所有網站需要伺服器驗証 別打勾)
// -----★ 2.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【起始不標示為安全的ActiveX控制項,請改為"啟用"】
// -----★ 3.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【存取各(跨)網域的資料來源,請改為"啟用"】
// -----★ 4.打開IE-->工具-->網際網路選項-->安全性-->信任的網站--> 自定層級中
【在較少特殊權限的網頁內容區域中的網站可以瀏覽,請改為"啟用"】(非必要選項
)
// -----★ 每次執行上傳前,請把NT重開一次,以確保內存是清空狀態下的
// -----★ 上傳檔案之絕對路徑不得有中文字!!
// -----★ 強烈建議 MAX 20MB per file. (可視個人配備調整)
Label:begin
go:http://www.turboupload.com/
WaitWebText:TURBO UPLOAD,3,begin
//--- 取得冏2的資料
ItemToVariable:uploadp_id,***Variable2***
CreateEngName:***Variable3***,***Variable4***
//--- 建立冏3的資料
SetDataValue:UP BY ***Variable3*** (***Time***),***Variable5***
//--- 取得Post_Action
WebStrToVariable:action=, method=post,***Variable6***
//------ 檔案上傳 by Ajax
Label:GetFile
GetFile()
IFNo:end
Label:up-page
go:about:blank
sleep()
AddWebHtml:<textarea name="FilePath" rows="1"
cols="40">***File***</textarea><p align="left"><span id="waitup"><img border=0
src="http://blog.xuite.net/_image/upload.gif" width="200" height="200"
></span></p>
sleep()
FindWebText:***File***
IFNO:up-page
RunScriptNext:var formDate = '--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="uploadp_id"'+'\r\n'+'\r\n'+'冏2'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="filetoupload";
filename="冏1"'+'\r\n'+'Content-Transfer-Encoding:
binary'+'\r\n'+'\r\n'+'{!--file--}'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="description"'+'\r\n'+'\r\n'+'冏3'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="terms"'+'\r\n'+'\r\n'+'checkbox'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="Submit"'+'\r\n'+'\r\n'+'Upload File'+'\r\n'+'--AaB03x--'
RunScriptNext:formDate=formDate.replace('冏1',document.all('FilePath').value);
RunScriptNext:formDate=formDate.replace('冏2','***Variable2***');
RunScriptNext:formDate=formDate.replace('冏3','***Variable5***');
RunScriptNext:function UniCodeToString(source) {var codeAry =
source.split("\/u");var sret = "";for(var i=0; i < codeAry.length; i++)
{if(codeAry[i]=="") continue;sret += String.fromCharCode("0x" + codeAry[i]);}
return sret; }
RunScriptNext:function strToChar(stream,charset){var str =""; var Stream = new
ActiveXObject("ADODB.Stream");Stream.Type = 1;Stream.Mode = 3; Stream.Open();
Stream.Write(stream);Stream.Position = 0;Stream.Type = 2; Stream.Charset =
charset ; str = Stream.ReadText(); Stream.Close(); Stream = null; return str;
}
RunScriptNext:function strToHex(str) { if ('' != str) { var st, t, i;st =
'';for (i = 1; i <= str.length; i ++){t = str.charCodeAt(i -
1).toString(16);if (t.length < 2) t = '0'.concat(t); st =
st.concat(t);}return(st.toUpperCase());} else {return('');}}
RunScriptNext:function loadFile(path) {stream = new
ActiveXObject("ADODB.Stream");stream.Type =
1;stream.Open();stream.LoadFromFile(path); binaryStream =
stream.Read();stream.close();stream=null;return binaryStream}
RunScriptNext:function byteToHex(byteStr) {var xmldom = new
ActiveXObject("Microsoft.XMLDOM");var byteObj=
xmldom.createElement("byteObj");byteObj.dataType =
'bin.hex';byteObj.nodeTypedValue = byteStr;return(String(byteObj.text));}
RunScriptNext:function hexToByte(hexStr) {var xmldom = new
ActiveXObject("Microsoft.XMLDOM");var byteObj=
xmldom.createElement("byteObj");byteObj.dataType =
"bin.hex";byteObj.nodeTypedValue = hexStr;return(byteObj.nodeTypedValue);}
RunScriptNext:sendbinary = hexToByte(
strToHex(formDate.split("{!--file--}")[0]) +
byteToHex(loadFile(document.all('FilePath').value)) +
strToHex(formDate.split("{!--file--}")[1]) );delete
binaryStream;CollectGarbage();
RunScriptNext:function loadHttpXML(post_action, sendObj , key_value) {var
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");xmlhttp.onreadystatechange =
xmlhttpReadychange;xmlhttp.open("POST", post_action,
true);xmlhttp.setRequestHeader("content-type", "multipart/form-data;
boundary=AaB03x");xmlhttp.send(sendObj);function xmlhttpReadychange(){if
(xmlhttp.readyState == 4){ var charresult =
xmlhttp.responseText.match(/CharSet=(\S+)\">/i); if(charresult == null
||charresult[1].toUpperCase() =='UTF-8') {var go=xmlhttp.responseText;}
else{var go =strToChar(xmlhttp.responseBody,charresult[1]);str=null;} ;
xmlhttp=null; if(UniCodeToString(key_value).length >1 ){var
key1=UniCodeToString(key_value)} else {key1=key_value}
;if(go.search(key1)!=-1) {document.all('FilePath').value='搞定'+go;} else
{document.all('FilePath').value='上傳失敗!!'+go;} ;}}}
RunScriptNext:loadHttpXML('***Variable6***', sendbinary , 'successfully
uploaded' )
sleep()
RunScriptNext:delete sendbinary;CollectGarbage();xmldom=null;
//--- 等待上傳結果的偵錯設計
Label:wait-up
WaitWebText:搞定,7,wait-up2
GoLabel:up-ok
Label:wait-up2
WaitWebText:上傳失敗,1,wait-up
GoLabel:up-page
Label:up-ok
ItemToVariable:FilePath,***Variable24***
GetstrToVariable:***Variable24***,Download-Link</strong>: <a
href=",",***Variable10***
output:***Variable10***
FileLoop:GetFile
Label:end
go:about:blank
output:<<所有檔案已上傳完畢>>
EXIT()

要寫一個免置頂上傳GDL,經Get-Ajax-Data.GDL生成後,最多只需改四個部份即可!!
第一部份是 RunScriptNext:var formDate ="" 的內容。其代表的也就是整個上傳表單需用到的所有欄位與其值加總。
所以 當上傳表單中有不固定之欄位值時,
我們就必需即時去取得該值,再代入formDate中來更替
而代替法就是用
RunScriptNext:formDate=formDate.replace('冏?','***Variable?***');
的模式!! 需要幾個就插入幾行
那有人會問,我怎麼知道哪些欄位是非固定的,每次都會變動的呢??
這個粉容易,你若怕直覺不準,那你只要取二次資料,分別另存。然後再利用如UltraEdit 等文書軟體的檔案比對功能。
不一樣的地方在哪裏便會一目瞭然囉!!
第二部份是指
上傳表單的 Action 值 !! 也就是
RunScriptNext:loadHttpXML(參數1,sendbinary ,參數2) 中的參數1 !!
若非固定就先取得再存入***Variable?*** 中,然後再以
RunScriptNext:loadHttpXML('***Variable?***', sendbinary ,參數2) 來表示即可!!
第三部份是指上傳成功時會出現的字眼!! 也就是 RunScriptNext:loadHttpXML(參數1,sendbinary ,參數2)
中的參數2 !!
這裏除了文字串外,也可以代源始碼或是將字串用Unicode跳脫序列來表示
第四大部份是從回傳頁中取得我們要的訊息!! 這裏與用原來的方式上傳一樣,只是現在回傳頁則是以源始碼的型態被我們存到一個自定變數中!!
所以原本用WebStrToVariable 的方式取頁面中的資料,現在則要改用 GetstrToVariable 來取自定變數中的資料!!

關於 指令、流程的應用,我前面已講的太多了,所以這部份將以講解四個需要修改的地方為主!! 剩餘的就請USER自行努力~
例子一:http://www.gigasize.com/
大家應該對這空間還有印象吧!! 之前被它整的半死…

那照樣是利用 Get-Ajax-Data.GDL 來自動生成GDL碼,再看要改哪些地方~
首先, RunScriptNext:var formDate 這裏不用改~
再來,Action的地方因為 sid 這個參數不固定,所以得即時取得代入
關鍵字的話,大家該還記得之前用表單的方式送出後,完全沒東西吧!! (忘記的人往前翻吧)
而我們用的正是模擬表單的送出方式,所以自然也是沒東西好回傳的~ 所以這裏關鍵字就保持空的就好~
Label:begin
go:www.gigasize.com
FindWebText:Files (maximum
IfNo:begin
WebStrToVariable:upload-multi.cgi?sid=,&,***Variable75***
RunScriptNext:loadHttpXML('http://www.gigasize.com/cgi-bin/upload-multi.cgi?sid=***Variable75***&description=',
sendbinary , '' )
例子二:http://www.1-click-upload.de/
go:http://www.1-click-upload.de/index.php
FindWebText:I accept
IfNo:GetFile
ItemToVariable:sessionid,***Variable7***
ItemToVariable:AccessKey,***Variable8***
...........
............
RunScriptNext:var formDate =
'--AaB03x'+'\r\n'+'Content-Disposition: form-data;
name="sessionid"'+'\r\n'+'\r\n'+'冏2'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="UploadSession"'+'\r\n'+'\r\n'+'冏2'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="AccessKey"'+'\r\n'+'\r\n'+'冏3'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="maxfilesize"'+'\r\n'+'\r\n'+'209715200'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="phpuploadscript"'+'\r\n'+'\r\n'+'http://1-click-upload.de/uploading.php'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="returnurl"'+'\r\n'+'\r\n'+'http://www.1-click-upload.de/cross.php'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data;
name="uploadmode"'+'\r\n'+'\r\n'+'1'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; na~
me="uploadfile_0"; filename="冏1"'+'\r\n'+'Content-Transfer-Encoding:
binary'+'\r\n'+'\r\n'+'{!--file--}'+'\r\n'+'--AaB03x--'
RunScriptNext:formDate=formDate.replace('冏1',document.all('FilePath').value);
RunScriptNext:formDate=formDate.replace('冏2','***Variable7***');
RunScriptNext:formDate=formDate.replace('冏3','***Variable8***');
formDate 的地方有三個是非固定值的,其中 sessionid 與 UploadSession 是同值的~
再來看Action 和關鍵字~
RunScriptNext:loadHttpXML('http://1-click-upload.de/cgi-bin/upload.cgi?sid=***Variable7***&maxfilesize=209715200&mode=ajax',
sendbinary , '上傳成功關鍵字' )
Action中的sid參數就與前面取到的 sessionid 與 UploadSession 是相同的~
至於關鍵字就比較麻煩~ 為何這樣說呢~
你手動至該頁面傳看看就知~

如上圖,它會慢慢顯示,直到 100% 時,才會把連結在連度條的右下角列出來~ (注意,這整個過程頁面是保持沒變過的喔!! )

根據我們之玩GigaSize 的經驗,這個空間應該也是兩段式的!! 意即傳完後,還要有一個檔案上架的動作!!
那就切換到【POSTDATA】標籤去看看~ 果然除了上傳那段外,下面還有另外一段~

從上圖來看就粉清楚~
第二段的檔案上架是靠第一段中的UploadSession 與 AccessKey 來告知SERVER 該檔已上傳完成!! (
聽不懂我在說什麼的人,表示你高估了你的功力了,回頭重修吧)
好,反正我們也不知關鍵字要下啥米,就先下 "Your Download-Link"
試試吧!!

如上圖,當程序走到 Label:wait-up 後,我們就立即按下程式的STOP鍵

再來就等結果~ 當然會看到失敗啦… 不過這是可預期的!!
那就把那格子的內容全COPY起來後,貼到網頁編輯軟體看看~

如上圖, 懂PHP 的人一看就知,其實它已正確上傳完成囉~
update server set hosted=hosted+1,webspace=webspace+243212 where server_id='1'
這個243212 就是我上傳檔案的大小,在SERVER那邊已經加上去了,所以上傳成功的關鍵字就用
"webspace=webspace+"
RunScriptNext:loadHttpXML('http://1-click-upload.de/cgi-bin/upload.cgi?sid=***Variable7***&maxfilesize=209715200&mode=ajax',
sendbinary , 'webspace=webspace+' )
那上傳完後檔案上架的動作也粉容易,只是它會跳出一個錯誤框說啥少了元件的,別理它!! 直接下指令關了它就好~
接著你會發現頁面是空白的,這個也沒差,按下檢視原始檔後,你就會看到我們要的東西了~
為何會這樣呢?? 你看上面有列的那二個上傳完成的圖就知!!
從上傳開始到最後的連結出來,它頁面完全沒刷新過!! 這個就是用到Ajax 來完成免重整更新頁面~
但我們是在空白頁執行檔案上架的動作,所以空白頁當然會沒地方可放生成的連結囉~ 結果自然是會跳出少了啥米又啥米的警告窗啦!!
DisableScriptError:1
Label:up-ok
postdata:http://www.1-click-upload.de/emaillinks.php?UploadSession=***Variable7***&AccessKey=***Variable8***&uploadmode=1&submitnums=0&fromemail=&toemail=&terms=on
FindHtmlText:have been uploaded successfully
IFNo:up-ok
WebStrToVariable:downloadhref href=",",***Variable10***
output:***Variable10***
例子三:xuite_photo
因為它的上傳頁面是在已登入的情況下,所以我們無法直接給定其網址來分析~
所以,我們可先手動將視窗焦點置於該上傳頁面後,再來跑 Get-Ajax-Data.GDL 就好~
如下,上傳前會有讓你選擇相簿的~

接著就會到達上傳頁面,把該處理的欄位搞定~
相片名稱或相片描述最好用上傳的檔名,圖片大小當然是不調整~
至於其它有的沒的我們就不填了!! 所以記得跑模組時,問到你要不要過濾掉沒值的欄值時,記得要直接按確定喔!!
(若不過濾當然也行啦,此GDL 也會依取得後的 formDate 長度是否超過900來自動幫你分行出來讓NT可以跑的。有興趣的人可以玩玩看)


在 Get-Ajax-Data.GDL 執行的過程中,出現了一個以往沒出現的對話框!!

這個意思是說,我們要分析的頁面裏,同時存在多個上傳表單~ !
那GDL就會自動把所有的上傳表單照順序列出,並附上其Action的值,讓USER可以依其來判斷要取哪一個表單~
例如這個頁面我們用猜的也知道該選第一個表單,因為我們要單張相片上傳嘛! 即填入 0 !
若選第二個表單,看它的Action 為 act_add_zip ,大概就是上圖中的
ZIP上傳 模式了~
前置作業處理好後,就來看生成的GDL碼需要改哪些地方~
首先看需即時處理的欄位~
ItemToVariable:ab_id,***Variable20***
....
....
RunScriptNext:var formDate = '--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="ab_id"'+'\r\n'+'\r\n'+'冏2'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="pic1"; filename="冏1"'+'\r\n'+'Content-Transfer-Encoding:
binary'+'\r\n'+'\r\n'+'{!--file--}'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="pic_title1"'+'\r\n'+'\r\n'+'冏3'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="pic_desc1"'+'\r\n'+'\r\n'+'冏3'+'\r\n'+'--AaB03x'+'\r\n'+'Content-Disposition:
form-data; name="smode_pic"'+'\r\n'+'\r\n'+'0'+'\r\n'+'--AaB03x--'
RunScriptNext:formDate=formDate.replace('冏1',document.all('FilePath').value);
RunScriptNext:formDate=formDate.replace('冏2','***Variable20***');
RunScriptNext:formDate=formDate.replace('冏3','***FileName***');
那個ab_id 就是指相本代號啦~ 所以我們必需要即時來取得~
至於後面的 pic_title1 與 pic_desc1 就是 相片名稱與相片描述,直接用 ***FileName***
來代就好~
再來Action的 部份是固定的,別理它~ 要處理的是上傳成功的關鍵字眼!!
那一樣先手動傳看看~

嘿嘿,上傳完成後竟是一個確認框~ 若我們用正常的方法來寫上傳,這個就粉要命了~
那就直接用 " 相片上傳成功" 來試試好了!!
RunScriptNext:loadHttpXML('http://photo.xuite.net/_my/act_add_pic', sendbinary
, '相片上傳成功' )
那一樣,看回傳的結果為何~

哈,看到"搞定"的字眼後,心情就美麗起來了,因為猜對了~ 
上面看到的那段JS 就是我們看到的那個對話框嘛,所以連框都不用閃了,萬事OK!!
剩下的取連結部份就屬USER 的課業囉(可用附錄一教的DOM分析法來取,粉容易的啦)
例子四:storeandserve.com
這個空間相當有意思,當我們把http://storeandserve.com/ 帶入Get-Ajax-Data.GDL
去分析時,你會發現頁面被引導至如下的畫面~

這表示該上傳表單是位於 iframe 內且它的src 與
http://storeandserve.com/ 的domain不同~
因為 JS 嚴格的跨網域安全限制,所以我只能將內框頁面引導出來~
若USER看到這種畫面的,就給它點那個 【點我進內框架頁】就是了~
好,那接著便會進入我們要處理的頁面了。再來就是將去【命令標籤】點下圖中的那行,再 start run in point 就是囉~

生成完GDL碼後,就開始來看看需要更改哪些地方~!
首先,RunScriptNext:var formDate 的地方短到不行,不用改~ XD
再來看 Action ~
RunScriptNext:loadHttpXML(下面黃色部份 , '上傳成功後頁面會顯示之字串(可用原始碼),字串也可用Unicode跳脫序列來表示' )
http://upload4.storeandserve.com/?uploads/upload&PHPSESSID=ea14965474a41010e9ed3506ae6316e7cgi-bin/upload/ajaxupload.cgi?serial=11764329604222&ses_usertype=F',
sendbinary
你會發現它長的好怪,這串網址並不符合正規的寫法!! 
http://upload4.storeandserve.com/?uploads/upload&PHPSESSID=ea14965474a41010e9ed3506ae6316e7cgi-bin/upload/ajaxupload.cgi?serial=11764329604222&ses_usertype=F
如上,我把它用二個顏色來分你就會看的清楚了~
後面紅粉色的部份是上傳表單中action 的值,其以相對路徑的方式來表達~
而前綠色部份則是該表單所在頁面的href ~
所以照理來說,把這兩個部份加起來就該是完整的Action 了~ ( 這也是我模組中Action 取法的流程 )
不過問題來了!! 因為這個頁面是從http://storeandserve.com/
裏另外被我引導出來分析的 !!
所以若以父窗的角度來看,內框頁所在的頁面該是在
http://upload4.storeandserve.com/
才對喔!!!
正確的完整 Action 該是長成如下才對!!
(這裏Action的部份無法直接處理是因為筆者在設計模組時是以大部通用為前題,對某些針對性強的寫法並不在此考量,請多見諒 !
)
另外,Action中的 upload4 就是上傳主機別 !! 例子裏我就用固定的 upload4 ,有興趣的人可自行加入一變數來指定它 ~
HttpStrToVariable:http://storeandserve.com/,PHPSESSID=,",***Variable4***
go:http://upload4.storeandserve.com/?uploads/upload&PHPSESSID=***Variable4***
FindWebText:file to upload
IfNo:up
WebStrToVariable:serial=,&,***Variable5***
SetDataValue:http://upload4.storeandserve.com/cgi-bin/upload/ajaxupload.cgi?serial=***Variable5***&ses_usertype=F,***Variable14***
......
RunScriptNext:loadHttpXML('***Variable14***', sendbinary , "上傳成功關鍵字眼" )
那接著就是上傳成功的關鍵字眼了!! 這裏一樣,我們先保持不動讓它去傳,再依回傳頁的訊息來判斷就好~

如上,那個上傳失敗的字眼粉正常,因為我們的關鍵字亂設嘛~
所以我會取 "uploaded successfully" 來作為關鍵字!!
再來,它回傳了一個表單給我,這個就是讓我們處理檔案上架用的!!
這個表單的 action 是用相對路徑,所以我們要自已補上前面的,例如 http://upload4.storeandserve.com (若你有指定主機,這裏也要記得更改)
再來就是兩個input 而已… 把它取一取,然後用 postdata 的方式給丟出去~
Label:up-ok
ItemToVariable:FilePath,***Variable19***
GetstrToVariable:***Variable19***,"hidSession" value=",",***Variable18***
GetstrToVariable:***Variable19***,hidFileName" value=",",***Variable17***
postdata:http://upload4.storeandserve.com/?uploads/uploaded_over_redirect?hidSession=***Variable18***&hidFileName=***Variable17***
再來頁面就會轉到生成連結的地方囉… 剩下的自已處理~
