Powerbuilder inet.PostURL用法

(转)Powerbuilder inet.PostURL用法   

目前PB的開發我都是把它當成一個 Remote Client UI,

所以實際上它沒有連接資料庫,而完全是透過Coldfusion的服務頁面完成資料操作,

因此很多時候需要傳遞大量資料時,簡單的 inet.GetURL 函數就變得不好用了,

因此特地研究了inet.PostURL的用法,它的用法在Help上有兩個範例(我有修改過):

第一種是簡單的呼叫一個頁面,並取得頁面回傳的HTML內容:
(請注意 linet 和 n_internetresult 都是必須先建立的物件與類別, 可參考這裡)

Blob lblb_args
String ls_headers , ls_url
Long ll_length
n_internetresult lir_html
inet linet

linet = Create inet
lir_html = CREATE n_internetresult
ls_url = "http://www.mydoamin.com/testpage.cfm"
lblb_args = blob("")
ll_length = Len(lblb_args)
ls_headers = "Content-Length: " + String(ll_length) + "~n~n"
linet.PostURL (ls_url, lblb_args, ls_headers, 8080, lir_html)

destroy lir_html
destroy linet

上面這種方式並沒有傳遞參數,其實效果如同:
linet.GetURL("http://www.mydoamin.com:8080/testpage.cfm",lir_html)



不過上述方式實際在執行時是有點問題,那就是Cache,如果你已經執行過一次這個方式,其回傳內容會被Cache在PBVM內,當下次再執行時,它並不會重新發出請求,反而直接從記憶體Cache中的內容重新取出並回傳。

解決的方式可以在要傳遞的內容不要放空值,隨便填一個東西,只是這樣子做真的有點多此一舉,不如直接使用  GetURL 還來得直覺些: 
lblb_args = blob(String(today()))
ll_length = Len(lblb_args)

第二種方式帶有傳遞參數

Blob lblb_args
String ls_headers , ls_url , ls_args
Long ll_length
n_internetresult lir_html
inet linet

linet = Create inet
lir_html = CREATE n_internetresult
ls_url = "http://www.mydoamin.com/testpage.cfm"
ls_args = "user=John&pwd=123456"
lblb_args = blob(ls_args)
ll_length = Len(lblb_args)
ls_headers = "Content-Type: application/x-www-form-urlencoded~n" + &
                    "Content-Length: " + String(ll_length) + "~n~n"
linet.PostURL (ls_url, lblb_args, ls_headers, 8080, lir_html)

destroy lir_html
destroy linet

其實上面這種效果也同等於下面的方式
linet.GetURL("http://www.mydoamin.com:8080/testpage.cfm?user=John&pwd=123456",lir_html)

但若要傳遞檔案就要使用HTML表單的 HTTP multipart/form-data

方式來處理會比較妥當,因此在PB Help說明不甚清楚的情況下就必須研究一下

HTTP的相關協定了。

在HTTP的協定中有訂製 multipart/form-data 傳輸的方式為  rfc1867協定
這個協定的基本結構如下:

Content-Type: multipart/form-data; boundary=****20110908123520**** ~r~n
Content-Length: 299 ~r~n
~r~n
--****20110908123520**** ~r~n
Content-Disposition: form-data; name="user" ~r~n
~r~n
John ~r~n
--****20110908123520****~r~n
Content-Disposition: form-data; name="pwd" ~r~n
~r~n
123456 ~r~n
--****20110908123520**** ~r~n
Content-Disposition: form-data; name="txtfile"; filename="我的訂單.txt" ~r~n
Content-Type: text/plain ~r~n
~r~n
...我的訂單.txt的內容... ~r~n
--****20110908123520**** ~r~n
Content-Disposition: form-data; name="imgfile"; filename="我的照片.jpg" ~r~n
Content-Type: image/jpeg ~r~n
Content-Transfer-Encoding: binary ~r~n
~r~n
...我的照片.jpg的內容... ~r~n
--****20110908123520****-- ~r~n

可以看到 淺藍色部份就是它的 Header, 粉色部份就是 Arguments


  1. 在 Header 的地方 Content-Type:設定為 multipart/form-data;
  2. boundary 是用來定義分隔線的樣式,其內容可以自訂,一般而言都是亂數產生的文字,盡量避開會與內容發生相同的可能性。
  3. Content-Length: 是 Arguments (粉色部份全部)內容的總長度。
  4. Header 與 Arguments 中間由一個換行分隔(白色部份)
  5. 粉色部份則是 Arguments的內容,而裡面每一個 argument 都由一個 boundary 分開,
  6. 每一個作為分隔的 boundary 前面會再加上 --
  7. argument內容都會先定義其來源變數名稱:Content-Disposition: form-data; name="欄位名"
  8. 然後會加個換行表示此欄位對應值的資料開始,直到遇到下一個 boundary 結束
  9. 如果 argument 內容值不是單純的文字資料,則會視情況加上 Content-Type 或是 Content-Transfer-Encoding
  10. 最後,整個 Arguments 的結束由 boundary 前後各加上 -- 作為結束符號


由於 PostURL 的 Header 與 Arguments 分開傳輸,所以淺藍色與粉色的部份就必須分開處理。

下面展示一個上傳圖片的 Script:

Blob lblb_args , lblb_pic
String ls_headers , ls_url , ls_args , ls_bndy
Long ll_length
n_internetresult lir_html
inet linet
integer li_file

//讀取圖片
li_file = FileOpen("C:\myPic.jpg",StreamMode!)
FileReadEx(li_file,lblb_pic)
FileClose(li_file)
//建立網路物件
linet = Create inet
lir_html = CREATE n_internetresult
ls_url = "http://www.mydoamin.com/uploadpic.cfm"
//建立分隔字串
ls_bndy = "****" + String(cpu()) + "****"
//先產生其它argument資料
ls_args = "--" + ls_bndy + "~r~n" + &
              "Content-Disposition: form-data; name=~"user~"~r~n~r~n" + &
              "John~r~n" + &
              "--" + ls_bndy + "~r~n" + &
              "Content-Disposition: form-data; name=~"pwd~"~r~n~r~n" + &
              "123456~r~n" + &
              "--" + ls_bndy + "~r~n" + &
              "Content-Disposition: form-data; name=~"pic~"; filename=~"MyPic.jpg~"~r~n" +&
              "Content-Type: image/jpeg~r~n" + &
              "Content-Transfer-Encoding: binary~r~n~r~n"
//轉成binary後加上圖片資料與結束符號
lblb_args = blob(ls_args) + lblb_pic + blob("~r~n--" + ls_bndy + "--~r~n")
//計算Argumments長度
ll_length = Len(lblb_args)
ls_headers = "Content-Type: multipart/form-data; boundary=" + ls_bndy + "~r~n" + &
                    "Content-Length: " + String(ll_length) + "~r~n~r~n"
//Post方式上傳檔案
linet.PostURL (ls_url, lblb_args, ls_headers, 8080, lir_html)

destroy lir_html
destroy linet


注意:展示程式碼沒有檢查機制所以正常情況下該有的檢查還是要做,比如檔案開啟失敗等等,雖然你可以用PowerBuilder Exception來處理,但實際上不太建議。

附上 PowerBuilder 發送 http 請求的基本 Header 給大家參考:
POST /test/hello.html HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Content-Length: 16
User-Agent: PowerBuilder
Host: 192.168.0.155
Cache-Control: no-cache
Cookie: CFID=7835; CFTOKEN=15357209

2.0.1.1./.9./.9.

猜你喜欢

转载自blog.csdn.net/hyfound/article/details/52980408
今日推荐