2020/12/21

HOWTO UPDATE NPM PACKAGE


 

在開發專案時或多或少會採用 3rd party 套件進行開發,當套件出現問題時我們會有以下選擇:

  1. 裝作沒看到它,忽視。
  2. 自行開啟原始碼修復。
  3. 等待廠商更新來修復這些問題。

1 和 2 選項都很好,但我個人偏好採用第 3 項, 專業分工是我的中心思想,但問題來了,該如何自行更新,又或是如何檢查專案,按步驟說明如下:

2020/12/09

Classic ASP ADO 開發注意事項

Classic ASP 使用 ADODB 常數時,發生程式無法執行的情況

Classic ASP 的 ADO 撰寫時遇到常數不存在的問題,例如:

1
cmd.CreateParameter("v_CdEnt", adChar, adParamInput, 4, Request("ENTIDADE"))

adChar 和 adParamInput 會因為不存在其常數而頻頻報錯,經查詢才發現是 VBScript 並不會內建這些常數,不只是 Classic ASP,Word、Excel 也一樣。

解決的方法有三種:

2020/12/08

Github DataSet Helper 試用


 在 Delphi developer FB 社團看到 DatasetHelper 開放原始碼單元。

功能

針對 TDataSet 進行聚集處理,如:加總 SUM、平均 AVG、計數 COUNT 等,也擴充正序 ForEach 和反序 ForEachReversed 函式讓開發者可以進一步處理每一筆資料。

2020/11/03

[React]Functional Component 製作上下層共用元件方法

 

源自:【學習筆記】React 边做边学(从零开始,包含Hooks)【25, 26. 彈出組件】一節。

課程中使用 Class 元件設計,CodeSandbox Demo1

看著 Panel 開開關關,心想使用 Functional 元件重新設計應該不是件難事,沒想到在做完之後跳出錯誤訊息:


Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: null.

為什麼會得到這樣的錯誤訊息?【Class Instance】

訊息內大致上是說:在應該有值、元件的位置卻得到 null。原因是 ES6 在建立 Class 時會帶有 Instance,典型語法就是【this】應用,this 在 Functional 元件是不受支援的。

題外話,Classes 在 MDN 中對物件導向迷思的解釋:

ECMAScript 6 中引入了類別 (class) 作為 JavaScript 現有原型程式(prototype-based)繼承的語法糖。類別語法並不是要引入新的物件導向繼承模型到 JavaScript 中,而是提供一個更簡潔的語法來建立物件和處理繼承。
實在是看不出 React 中用 Classes 來寫有簡潔的趨勢,不知你是否也和我有一樣想法?

2020/10/28

【學習筆記】React 边做边学(从零开始,包含Hooks)

重温 REACT Functional Component,本篇沒有完整結構,純筆記用途。

課程使用套件

  • BULMA 樣式元件
  • React Transition Group 動畫元件庫

 

容器排版

課程的主畫面排版由小到大依序由綠、黃、橙、紅高亮,配置如下:

綠色:Product 元件,在 Products 下,顯示產品圖片、金額和加入購物車等功能。

黃色:同位階有 ToolBar 和 Products 元件,在 ProductList 下,分別處理產品搜尋和產品清單的顯示。

橙色:同位階有 Header 和 ProductList 元件,在 APP 下,分別處理產品搜尋和產品清單的顯示。

紅色:APP,最大容器,主畫面是也!

My JSON Server -- 偽線上 REST 服務


開發 JavaScript 前端程式時,為了架設方便性,會使用類似 CodeSandbox 的前端線上程式編輯器進行測試,開發速度很快,對學習有加乘效果。

缺點就是在需要和後端 API 進行連結測試時,內部的 Web Server 往往還沒有在網際網路上公開,當然也就無法完整測試前端效果。這時就可以使用【My JSON Server】來模擬後端應用。

2020/10/15

Delphi 10.4.1 對 DataSnap 相關修正一覽


Delphi 10.4.1 人品大爆發,大幅修正許多陳年臭蟲,讓人驚豔!以下是從官方網上文件節錄我覺得很有意思的修正項目。

2020/10/10

Windows 10 升級 2004 版後更換微軟倉頡碼表

 

在學習倉頡五代後,一直覺得微軟倉頡和新倉頡的倉頡四代碼表很不友善,一直到最近看到倉頡之友的【替換微軟倉頡碼表,盡享倉頡補完計劃的樂趣】,才知道原來微軟倉頡也可以更新碼表,終於能享受到輸入文字的樂趣了!

 首先,Windows 10 要更新到 2004 版本。


倉頡碼表下載點

倉頡三代補完計劃替換碼表下載地址:https://github.com/Arthurmcarthur/Cangjie3-Plus/releases

倉頡五代補完計劃替換碼表下載地址:https://github.com/Jackchows/Cangjie5/releases



安裝步驟

  1. 任務管理器裏結束兩個Microsoft IME進程。
  2. 進入 C:\Windows\System32\zh-hk 目錄,刪除
    • ChtCangjie.sdc
    • ChtCangjie.spd
    • ChtCangjieExt.lex
    三個文件(刪除前請備份),然後將此處提供的 ChtChangjieExt.lex 重新命名為 ChtCangjieExt.lex,並複製到該目錄。

  3. 打開「包含香港增補字符集字元(HKSCS)」開關。

更多細節請閱讀補完計畫說明檔。

總結

使用倉頡補完計畫優點

  • 字碼編排最貼近符合倉頡歷代改版標準。
  • 可以使用倉頡五代輸入方式。

使用倉頡補完計畫缺點

  • Z開頭的符號碼無法使用,只能使用微軟輸入法的符號快速輸入鍵輸入。

整體來說優點大於缺點,能暢快享受輸入文字的樂趣,在這邊分享給大家。

2020/09/16

Delphi JSON Objects framework 處理效率

 


最近在李維老師的部落格看到關於 JSON 的新文章【RAD Studio的JSON處理效率】,主要在描述 TJSONReader 和 TJSONWriter 物件經過重新設計後所推出的 10.4.1,其效率提升的幅度。

對於專門寫中間層服務的我來說,JSON 也是門必須的功課(另一門是 XML for ClientDataSet),從李老師的文章可以得知使用的框架是【Readers and Writers JSON Framework】,在這邊引用官方新版文件內容:

2020/09/09

Code Insight Between Delphi 10.4.1 and Cnpack

 


Delphi 10.4.1 的【程式碼提示功能】進行很大的改良,除了功能演算法最佳化外,對我們有什麼影響呢?

2020/09/07

理解 React useEffect 02

前情提要

在【理解 React useEffect 01】一文了解到 useEffect 的功能是:

useEffect 主要在呈現 (Render) 後觸發此 Hook 事件,並將取得的資料後再呈現到元件上。

也知道我們要怎麼在 useEffect 裡面拉 WebAPI 的資料;且已知 useEffect 再觸發的條件是:第二個參數【依賴 dependency】發生變化時,就會再觸發 useEffect 掛勾。

這一篇將會告訴各位,如何手動觸發 useEffect,達成程式碼重用的目標。

2020/09/04

理解 React useEffect 01


React 中,取得資料並呈現到畫面上一直是個難題,useEffect 就是讓元件呈現【副作用 (Side Effects) 效果】一樣,對我們造成了很大的【副作用】的【效果】。

useEffect 要解決什麼樣的問題?

useEffect 主要在呈現 (Render) 後觸發此 Hook 事件,並將取得的資料後再呈現到元件上。

在【How to fetch data with React Hook?】一文中卻提到:

Note: In the future, React Hooks are not be intended for data fetching in React. Instead, a feature called Suspense will be in charge for it.
這句話中文大概的意思是:

未來 React Hooks 不會用在資料取得的場合,會改由 Suspense 取代。

可是 Suspense 也說明它不會取代 fetch、axios 等取得資料的 API,在目前有限的資料只知道未來還會變化,所以現階段學習 useEffect 是必須的,待情勢明朗後再來調整也來得及。

2020/08/27

【翻譯】建立 DevExtreme React 應用程式

來源:Create a DevExtreme Application
無責任翻譯:大匠之風 Eden Wu


如果你使用 DevExtreme 模板從頭建立專案。它是個帶有導覽列和數個支援響應式佈局的展示視圖之簡單應用程式。

2020/08/21

Destructuring assignment at REACT Function Component

 

React 學習時一定要記得一個概念,它就是 JavaScript,不管看到什麼,或是沒看到什麼,它就是 JavaScript,而且是支援最新標準的 JavaScript。

為什麼會這樣說?是因為要有 ES6 的概念,看 React 程式碼才有機會看懂!例如,今天要說的主題:【解構賦值(Destructuring Assignment)】。

2020/08/19

用 REACT 思考 -- 使用 Function Component

 

React 的核心概念是【物件】,學了它好一陣子,一直感受到 React 的 Class Component 受制於 JavaScript 語法糖框框是一種半吊子的解決方案。

在 REACT 16.8.0 開始支援 HOOKS 後,Function Component 這種貼近 JavaScript 設計概念的正規作法終於獲得改善,HOOKS 也是源自 Class Component 的提取,也有更多的改善之處,除此之外,有沒有更加地好學、好上手,我想才是支援 HOOKS 後所需要關心的地方。

2020/08/14

The SameSite attribute of the Set-Cookie in WebBroker Response

前陣子在陪好友練習 Cookie 操作時,無意間發現瀏覽器跳出一個奇怪的警告訊息:

一查才發現原來是瀏覽器為了防止儲存的 Cookie 被送到其它網站服務器所作的安全機制。

若現在不理它,未來可能會被瀏覽器無視,所以先來了解要如何解決。

2020/08/08

跨來源資源共用CORS處理方式(一)

 

寫對外公開 WebAPI 時,會因為瀏覽器安全性的關係而禁止非同源存取。

如以下範例:

2020/07/29

Delphi in Depth DataSnap 網站應用程式全端開發 出版



購書連結:
書本下載連結:PDF
範列下載連結:Github

內容簡介
  讓你從 0 到 1 進入全端開發領域,掌握後端知識同時也學會前端開發訣竅,點開 Web 開發新技能
   
  Delphi 進階框架 -- DataSnap 全方位構築後端知識。
  jQuery EasyUI 前端技術內涵及接近 VCL 元件的操作概念。
  資料庫常用操作。
  涵蓋語法入門,元件介紹等前後端整合實戰應用。

  給需要本書的人:
  ★有接觸過 JavaScript 卻不知道如何開始才能點開後端技能的人
  ★有接觸過 Delphi 但又不想打掉重練的人
  ★老是寫不好 Delphi 程式的人
  ★想運用 DataSnap 開發全端專案的人


本書特色

  1.本書採漸進式開發後台管理系統的全端網站應用程式,讓學習者能馬上做,立即學。
  2.全書程式碼毫無保留的呈現,重點處還會節錄再說明,更加強化理解與記憶內容。
  3.提供關於框架原理的圖說,讓讀者更能聚焦學習重點上。
  4.實作成品能立即應用在實戰中,實現超速學習成果。

專文推薦

    Eden 是我見過對 Delphi 最有愛的工程師,沒有之一。__【Delphi.KTOP 資深版主 Jason Wong】
   
    Eden 的堅持,是目前台灣地區 Delphi 不可或缺的精神,我從這本書裡面看到 Eden 的用心。__【Indy TIdDNSServer、Delphi / Kylix -Indy 網路程式設計作者 張子仁】

    本書從前端的 Javascript 說起,漸近地深入後端 DataSnap 實作,最後將前後端串起來,這樣的佈局,尤其對全端不熟的開發者而言,相信可以很快速的入門與應用 !__【Delphi.KTOP 副站長 蕭沖】

2020/05/08

Preserving State in DataSnap REST Server



DataSnap REST Server 有儲存狀態的能力,這取決在LifeCycle的設定值。

DataSnap REST Server 儲存狀態方式一:LifeCycle

LifeCycle 的【狀態範圍】在TDSServerClass實例(Class Instance);有 Server, Session(Default), Invocation 三種,影響 TDSServerClass 實例(class instance) 的生命週期。

2020/05/06

JavaScript ES6 call DataSnap API with Promise Fetch

在【Async callback in JS DataSnap Framework】裡有提到可以使用【Handling the Result】,也就是Callback function,如此就能避免掉在XMLHttpRequest中已被棄用的【同步請求(Synchronous request)】。

不過呢,有一好就沒有二好,寫著寫著,我的程式碼就變得和下圖一樣:
傳說中的回呼地獄(Callback hell)
圖:取自網路

聽說JavaScript新標準ES6裡的Promise,它的出現就是為了解決Callback hell而發展出的解決方案。

2020/03/12

Delphi Easy Excel 基礎類別設計


Excel是許多從事行政人員必用且愛用的工具之一,所以在程式開發上最常遇到的就是客戶拿產品來和Excel做比較。


這能比嗎!(怒吼)


忠孝不能兩全的情況下,拿Excel檔案進行匯入似乎是很常見的折衷方案。

Delphi號稱VB Killer,操作個Excel自然是基本款,來看看Delphi準備了哪些方案?

Microsoft Office 2000/XP Sample Automation Server Wrapper Components

Microsoft Office 2000/XP Sample Automation Server Wrapper Components


Delphi很貼心的提供Office元件,自Delphi 7~10.3以來,也就這麼兩套。(2020.03.19更新:XE5之後有單獨提供 2010 套件,但只要 Office 更新也是會有相容性問題。延伸閱讀:Delphi XE5 Office 2013 组件更新)

Office 至目前為止已經2019了,許多使用者都開始使用XLSX新格式,這個元件很早就出現相容性不足的問題。

另一個類似元件的做法是使用Import ActiveX Control,匯入新版Excel ActiveX控制項,實務上還蠻類似元件的操作方式,只是問題在Excel升級後仍有可能會有相容性問題產生。

3rd party

三方元件最好的地方在於使用者電腦並不需要安裝Excel即可進行XLS檔案操作,速度和品質都非常好,我用過的有:

NikaSoft NativeExcel

NativeExcel設計上非常貼近OLE的操作方式,在轉換上十分方便,操作XLS檔效率也非常棒,體驗後就離不開它。

但NativeExcel現在已經沒有維護,對XLSX相容性問題也開始浮現。

無奈之餘,還是只能忍痛放棄它。

XLSReadWriteII


這套是資深Delphier Jason Wong 愛用的Excel元件,而且仍有維護,據稱其優點和NatvieExcel相同,但設計概念非OLE操作,所以沒有深入了解。


看來看去,似乎只能回歸OLE設計方式才能達到最高相容的可能性。

畢竟穩定比效能更加重要!

使用OLE開發


使用官方元件很像是使用全域變數的概念,如果OLE也這樣設計如何?


var FExcelApp: Variant;

function ExcelApp: Variant;
  function IsExcelInstalled: Boolean;
  var
    ClassID: TCLSID;
    strOLEObject: string;
  begin
    strOLEObject := 'Excel.Application';
    Result := (CLSIDFromProgID(PWideChar(WideString(strOLEObject)), ClassID) = S_OK);
  end;
begin
  if IsExcelInstalled then
  begin
    if VarIsEmpty(FExcelApp) then
      FExcelApp := CreateOleObject('Excel.Application');
    Result := FExcelApp;
  end
  else
    WinMsgBox.WinError('Not found Excel, call EdenWu, please.');
end;

procedure CloseExcelApp;
begin
  if not VarIsEmpty(FExcelApp) then
  begin
    FExcelApp.ActiveWorkBook.Saved:= 1;
    FExcelApp.DisplayAlerts:= 0;
    FExcelApp.ActiveWorkBook.Close(SaveChanges:=0);
    FExcelApp.Quit;
    VarClear(FExcelApp);
    FExcelApp:=Unassigned;
  end;
end;

initialization
  //FExcelApp := unassinged; // this should not be necessary
finalization
  CloseExcelApp;

把Excel Application視為全域變數,隨時要使用Excel Application都沒問題,非常方便。

開始要寫一些關於Worksheet相關的處理了。咦?

好像還不錯,但不夠OOP,還要更多的OOP

寫著寫著,全域變數和全域函式跑來跑去,程式碼看起來就不夠簡潔了,如果使用OOP設計方式會不會更好呢?

自己刻好像不錯,只是有個臨摹的對象更好,來看看有沒有好範本可以參考。

Github搜尋一陣後,發現有高手寫了個SimpleExcel,仔細看了下程式碼,嗯,很OO,這我可以。

這樣的程式碼要自己來寫到底要花多少時間呢?
如果站在巨人的肩膀上會不會省下更多時間做更重要的事呢?

一邊使用SimpleExcel的同時,一邊思考著。


-全文完-

See also

2020/03/04

外掛小幫手FastReport

原來是報表工具啊,我還以為是外掛開發程式呢! (笑)


Delphi最有趣的地方是它有很多三方元件可以支撐開發專案,以上圖為例,功能不多,通常列為小專案,這時使用諾大的Delphi開發專案顯得太小題大作。


這時FastReport就派上用場,FastReport雖然是報表工具,別小看它,它搭載的Report Designer備有Pascal直譯功能,還有內建VCL基礎元件,有效利用下,可以大幅減少小專案開發時間,還能降低Delphi升級所帶來的改版衝擊呢!


報表工具當然要著重在報表的設計,Report Designer提供的函式庫想當然是不夠使用。FastReport也明白這點,便在FR Document也寫了很多的輔助說明,在藉助FR Document的神奇力量後,我也添加了許多常用函式到Report Desinger中,開發起來便利度提高非常多!


除了可視元件外,像是常常用到的TStringList基礎類別也有提供,程式寫起來超安心。


還有ADO, DBX等資料庫元件,用了Report Designer,很多小型專案都在移轉到FR後就刪除,專案存放目錄差點手殘到刪光光!


和Delphi一樣可以下中斷點,這Debug很可以。

一想到Delphi要開個幾十秒,開啟FastReport Report Designer不僅快,刻起程式也是趣味十足,提供各位參考。


See also

購買連結:Fast-Report官方網站

2020/02/19

Json SQL (JSQL) 概述

打造自己的GraphQL!
縁起

研究GraphQL後,發現它和SOAP的概念蠻像的,要先製定出前後端都認識的Schema,查詢的方式就是透過Schema放入查詢條件,很特別的是GraphQL可以在1次查詢取得多個Schema或多個查詢結果。省下很多Client發送Request/Response交握的時間成本。

SOAP的WSIL(WS-Inspection document)很類似GrapQL的Schema

2020/01/31

GraphQL使用評估

在學習React的過程有接觸到GraphQL這個新名詞,簡單來說GraphQL是:
一種新興的JSON Remote Procedure Call (RPC)規範
REST API寫多了,不是發展出一套龐大的路由切換器就是龐大的參數解析器

路由切換器
/person/id
/friend/id
/person/id/friend
...

參數解析器
persion_id=id
friend_id=id
...

如果系統簡單還好,但當系統一變多或變大,一定會有以下的問題:
  • API根目錄(ROOT)數量爆增,後端專案管理是個問題
  • API一旦異動(常見型別不同或欄位異動),前端必須等待後端更新,徒增開發效率不彰
GraphQL制定了前後端規範,只要後端Schema制定好,前端即有極大自由,減少工程師橫向溝通的時間就能加快開發速度。

使用GraphQL就能飛天?

前面說到,GraphQL嚴格來說僅止於制定規範,實作也只有提供簡易的Server讓使用者【嘗鮮】,實戰使用GraphQL往往需要搭配三方工具:Apollo或Relay,看來也是一條漫漫長路。

或許我們直接取用GraphQL的概念進行實作會更佳合宜。

能不能再簡單一點?

GraphQL到目前為止還是很新的技術,目前已知的資訊還不算成熟,如果自己採用類似JSON ORM的概念是否會更加簡單?

以上是目前對GraphQL一些看法,提供各位參考。謝謝各位觀看!

See also





2020/01/30

【前端】實戰 ASP.NET C# 移轉到 REACT 03



上回提到Main的作法之後,就要把前端做個完整的Prototype,讓前端歸前端,後端歸後端。

完整範例在此:eden-first-todo-list-app

2020/01/22

【前端】實戰 ASP.NET C# 移轉到 REACT 02



上一回提到登入頁面製作後,這次要帶實作主畫面。

原本主畫面長這樣:
 修改時會另開視窗進行編輯:
當時是利用後端進行 HTML 繪製,也就是 Server side 的處理方式,現在使用 REACT 會擦出什麼火花呢?

當時不會排版,不會CSS,連HTML標籤都知道的很少, 所以排版方式使用 Table 處理,就如同上圖的畫面。

REACT + Bootstrap 對 Table 不是太友善,我在 Caption 屬性就卡關了。

故用 Tabs 和 ListGroup 進行排版,畫面如下:

2020/01/21

【新聞】土耳其教育部添購百萬套Delphi授權



TIMETURK(土耳其官媒)在 2020/01/16 發表關於土耳其教育部購買百萬套 Delphi 授權的新聞。

其中說到土耳其國家教育部(MEB)和 Bilgi ve Teknoloji Grubu (BTG)簽了 5 年約,並購買百萬套 Delphi 授權供 1600 所職校近百萬名學生使用,個人猜測是以教育版為主。

買了這麼多 Delphi 版權是要用在哪裡?

2020/01/17

form + API 的兩種方式比較

一個 form post 也可以繞個一大圈


網頁傳統 form 要傳遞參數值時,會使用 action,寫法大致如下:

  <form action="http://localhost:8080/login" method="post">
    <h1>Form Action Test</h1>
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>

可以看到 submit 時,Request 的 Content-Type 屬性是很標準的 application/x-www-form-urlencoded。



這個方式很標準,絕大部份的 Web Server 都可以接受,當然也包含了 Delphi Web Server。

時代在進步,JavaScript 標準都來到 2020,所以當然要試一下新的操作方法。

JavaScript 裡有 FormData 類別,可以建構 form 物件,寫法如下:

  <form id="login-form" onsubmit="handleSubmit(event)">
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>
  
  <script>
  function handleSubmit(event) {
    event.preventDefault()
    let formData = new FormData(document.getElementById('login-form'))

    fetch("http://localhost:8080/login", {
      method: "POST",
      body: formData
    })
  }
  </script>

實際 submit 時 Request 的 Content-Type 屬性是 multipart/form-data,如下圖所示:




multipart/form-data 相對於 application/x-www-form-urlencoded 比較少見,故某些 Web Server 預設是不會處理 multipart/form-data 的格式內容。

既然後端需要做調整,如果前端事先做好,那後端不就更省事?

前端調整

仿照傳統規則

前端仿照傳統的作法實作,程式碼如下:

  <form id="login-form" onsubmit="handleSubmit(event)">
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>
  
  <script>
  function handleSubmit(event) {
    event.preventDefault()
    let formElement = document.getElementById("login-form")
    let formData = ""
    formData = "email=" + formElement[0].value
    formData = formData + "&password=" + formElement[1].value
    fetch("http://localhost:8080/login", {
      method: "POST",
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: formData
    })
  }
  </script>

執行結果


修改後就能讓 Web Server 順利解析參數。

使用 URLSearchParams

URLSearchParams 是個處理各種URL查詢參數轉換的類別,在這個例子只需要將 FormData 再丟入 URLSearchParams 處理過,即能得到 application/x-www-form-urlencoded 所需的查詢參數,程式如下所示:

<html>
<head></head>
<body>
  <form id="login-form" onsubmit="handleSubmit(event)">
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>
  
  <script>
  function handleSubmit(event) {
    event.preventDefault()
    let formData = new FormData(document.getElementById('login-form'))
    var searchParams = new URLSearchParams(formData);
    fetch("http://localhost:8080/login", {
      method: "POST",
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: searchParams
    })
  }
  </script>
</body>
</html>

執行結果


一樣修改後就能讓 Web Server 順利解析參數。


總結

新方法但沿用舊觀念,在某些前端框架看不到的細節還是要拆成香草JS小部件來多做嘗試才行。

前端修改下我會偏好使用 URLSearchParams,在開發上比較省力,程式也比較好懂。

以上提供各位參考。謝謝大家收看!


【2021.05.18 更新】

jQuery 和 form 的結合


<html>
<head>
  <script
  src="https://code.jquery.com/jquery-3.6.0.js"
  integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
  crossorigin="anonymous"></script>
</head>
<body>
  <form id="login-form" onsubmit="handleSubmit(event)">
    <input type="text" name="email" value="Eden" />
    <input type="password" name="password" value="L@veEden" />
    <input type="submit" value="Submit">
  </form>
  
  <script>
  function handleSubmit(event) {
    event.preventDefault()
    const formData = {user:document.getElementByName("user").value, password:document.getElementByName("password").value}
	
	// item 的內容也可以用 $.ajax.beforeSend 替換
	const item = {
		'url': "http://localhost:8080/login",
		'type': 'POST',
		'headers': {
		  'Authorization': `Basic ${ base64Auth }`,
		},
		//'contentType': false, // Default = application/x-www-form-urlencoded
		//'processData': false, // false = jq 不轉譯 Json to Parameters; Default=True
		'data': formData
	}

    $.ajax(item)
      .done(function (response) {
        console.log(response)
      })

      .fail(function (response) {
        console.log('Fail : ' + response.responseText)
      })
  }
  </script>
</body>
</html>