搜尋
首頁web前端js教程使用Node.js連接到Jawbone UP API

使用Node.js連接到Jawbone UP API

作為開發人員,我不禁要訪問我的Jawbone對我的大量步驟計數和睡眠習慣數據。有很多數據!因此,我開始研究如何使用Jawbone UP API和Node刪除此數據。

>我找到瞭如何使用Jawbone UP API和節點在網絡上使用的示例,但是它們都非常參與其中,並且有很多活動部件以及一些過時的模塊(例如Express的較舊版本)。在本文中,我想關注絕對基礎知識 - 不必擔心將用戶數據保存到數據庫中,創建帳戶或連接社交登錄。我們將重點介紹您需要知道的核心內容,以獲取節點服務器以使用Jawbone API進行身份驗證並返回用戶數據。

該演示的所有代碼都可以在我們的github repo上提供。

鑰匙要點

>使用Jawbone UP API使用Node.js訪問諸如步驟計數和睡眠習慣之類的大量用戶數據,而無需處理用戶數據存儲或帳戶管理的複雜性。 >

首先在Jawbone開發人員網站上設置Jawbone應用程序,以獲取必要的憑據,例如客戶ID和App Secret,這對於API集成至關重要。

>用Node.js中的OAuth 2.0實現護照模塊,以安全地處理用戶身份驗證和數據檢索。
    確保通過HTTPS進行與Jawbone UP API進行的所有通信以滿足安全協議並避免數據截距。
  • >使用Node.js中的EJS模板從Web應用程序上的Jawbone UP API中動態顯示已檢索的睡眠數據。
  • >探索通過從Jawbone UP API集成更多數據類型的更多數據類型,並可能與其他API結合以增強功能。
  • >設置Jawbone應用
  • >我們需要的第一件事是在我們的Jawbone帳戶下設置的新Jawbone應用程序。這是用戶將授權訪問其數據的應用程序。
  • >
  • 首先登錄Jawbone站點的開發人員部分,然後訪問https://jawbone.com/up/developer,然後單擊左下方的“登錄”鏈接。您將不需要特定的Jawbone開發人員帳戶,因為它們可以允許您使用現有的Jawbone帳戶登錄。
  • >登錄後,請訪問https://jawbone.com/up/developer/account,或單擊“帳戶”下左手菜單中的“管理帳戶”鏈接。

>在此頁面上,您將聯繫您的開發人員帳戶頁面。從這裡,單擊“創建應用”。

在加載的頁面上

>您將被提示輸入應用程序的詳細信息:>

  • >名稱 - 您的應用程序的名稱,我輸入了“ jawbone up node demo”。
  • 描述 - 這是一個簡短的描述,將在用戶的UP應用程序庫中出現。
  • 長描述 - 這是在應用程序畫廊的應用程序的詳細頁面上出現的。
  • >
  • 徽標 - 上傳您的應用程序徽標。如果您收到有關“選擇”的錯誤(我知道很奇怪,但是對於少數跟隨並收到信息的人來說是有意義的),那麼可能是您的徽標圖像太大了。
  • >
  • URL - 您的應用程序主頁
  • >
  • 授權URL - 您的登錄頁面的URL。出於我們的測試目的,請在https:// localhost中輸入:5000/login/jawbone。
  • >
  • > oauth重定向uris - 允許您的應用程序重定向到用戶身份驗證後的URL。在我們的演示中,我們將輸入https:// localhost:5000。
  • >單擊以創建應用程序後,您將使用應用程序列表將您定向到頁面。您新創建的應用看起來與我的外觀相似:

請注意“客戶端ID”和“ App Secret” - 這些是您需要連接到Jawbone API的方法。 使用Node.js連接到Jawbone UP API

啟動我們的節點應用

>我將在一個名為server.js的文件中包含所有我們的節點服務器代碼。我們首先需要服務器的必要NPM模塊。

>

首先,我們設置了一個基本的Express App。

然後,我們需要EJS(嵌入式JavaScript),這使我們能夠將JavaScript插入我們的HTML模板中。我們將使用它在我們返回的HTML中顯示JavaScript變量。 為了能夠使用Jawbone API進行身份驗證並將其重定向回我們的應用程序,Jawbone要求我們將其重定向到HTTPS上的頁面。為此,我們必須包括https。

<span>var express = require(‘express’),
</span>    app <span>= express(),</span>
接下來,我們包括FS,它允許我們讀取文件系統。我們需要在服務器證書文件中讀取以啟用HTTPS。

>

ejs <span>= require('ejs'),</span>
>我們還需要身體偏好器才能使我們能夠處理JSON請求:

https <span>= require('https'),</span>
jawbone UP API使用OAuth 2.0協議進行身份驗證。基本上,這意味著要通過用戶登錄其Jawbone帳戶並允許我們訪問其數據,我們需要仔細研究此協議。幸運的是,NPM的護照模塊包含一個稱為Passport-Oauth的模塊,該模塊支持這一點。我們將Passport與Oauth 2.0一起在應用程序中設置好:

>

然後,我們有一個自我解釋變量,該變量存儲了我們將要運行的端口。 >
fs <span>= require('fs'),</span>
接下來,我們將在Passport和JawboneAuth中存儲身份驗證所需的所有值。這是您在註冊應用時提前註意的“客戶端ID”和“ App Secret”值的時刻。

<span>var express = require(‘express’),
</span>    app <span>= express(),</span>

這是這些價值的含義和/或它們來自何處的概述:>

    clientId - 這是您的Jawbone應用程序列出的“客戶端ID”。
  • 客戶端 - 這是下面的“應用程序秘密”值。 >>
  • 授權庫 - 這是UP OAuth 2.0身份驗證頁面的位置,將用戶重定向到。
  • Tokenurl - 這是Jawbone UP API中的URL,我們必須調用HTTPS,以請求訪問令牌。這個令牌是我們需要將其包含在給Jawbone UP API的電話中,以證明我們有權提出這些數據請求。在Jawbone UP API中,此令牌可以持續一年,因此您可以將其存儲在數據庫中,並將用戶連接到其Jawbone帳戶一年,然後才需要重新驗證它們。我們不會在本教程中考慮存儲用戶,但是如果您想進一步推動它,請記住。
  • >。
  • > callbackurl - Jawbone在我們網站上的URL將用戶成功地將用戶帶回他們成功地訪問其數據後。對我們來說,這是顯示睡眠數據的頁面。
  • >我們要定義的最後一個變量是我們的ssloptions,其中包含我們需要提供給服務器的所有詳細信息,以便我們使用HTTPS運行此服務器。在解釋我們如何設置https時,我將在本文稍後詳細介紹所有這些。
  • > 然後,我們包含一些定義一些基本節點應用功能的行,這些app功能將為節點開發人員熟悉:

> BodyParser - 允許我們解析JSON對象。 >

>靜態文件夾 - 定義了我們的靜態文件(如映像)在服務器上的位置(在我們的情況下, /public文件夾)。

> EJS - 分配EJS模塊為我們的模板引擎。

視圖文件夾 - 定義了我們的EJS視圖文件將在服務器上的位置(在我們的情況下, /視圖文件夾)。
ejs <span>= require('ejs'),</span>
>
  • 為了在Express中初始化Passport,我們運行以下行:>
  • 注意,如果我們想持續登錄會話,請在護照中設置更多。在這種情況下,我們需要設置會議。但是,對於本教程,我們將重點關注從Jawbone UP API獲取數據的初始階段,而不必擔心登錄會話。
  • >
  • 設置我們的獲取請求
  • 為了將用戶引導到jawbone UP API的登錄屏幕,我們需要在服務器上分配一個URL,該URL將重定向到Jawbone登錄屏幕。為此,下面的代碼分配了 /登錄 /jawbone的URL。在獲得此URL的請求時,我們致電Passport.Authorize()啟動我們的Jawbone UP UP授權頁面:
<span>var express = require(‘express’),
</span>    app <span>= express(),</span>

>如上所述,我們有一系列我們要求的特定權限 - [basic_read','sleep_read']。在我們的情況下,我們要求提供基本的用戶數據和睡眠數據。如果您想要求訪問步驟數,用餐等等,則可以向該陣列添加其他許可請求。您可以在Jawbone UP開發人員身份驗證文檔頁面上查看可用的內容及其提供的訪問。

>另外,如果在Jawbone UP身份驗證屏幕中進行身份驗證失敗,它將將我們重定向回主頁。在護照模塊中也可能設置Scunstallect,但是我發現了Jawbone UP API,不需要,因為我們將在此代碼中進一步定義JawboneStrategy中的回調URL。 然後,我們設置了我們的睡眠數據將出現的Get請求。這是我們將告訴API將我們重定向到訪問用戶數據的位置。在此示例中,它是 /sleepdata:

>

>我們在此處具有相同的Passport.authorize()函數,只是為了檢查用戶到達此頁面時是否已登錄。如果是這樣,我們運行res.render('userData',req.account);它傳遞了jawbone UP API返回userData.ejs模板的數據(我們將盡快設置)。如果未登錄,它們將被指向jawbone UP身份驗證屏幕。

然後,我們設置一個URL以允許用戶在 /註銷處註銷,該網站將用戶重定向到主頁一旦登錄:>
ejs <span>= require('ejs'),</span>

>最後,對於我們的路由,如果有人試圖訪問主頁,我們將其設置為加載index.ejs模板:

使用護照連接到jawbone up api
https <span>= require('https'),</span>

>最大的代碼部分也是最重要的 - 建立護照“策略”來告訴Passport如何處理請求以授權使用'Jawbone'。看起來像這樣:

fs <span>= require('fs'),</span>

>讓我們介紹所有這些代碼正在做的事情。

>

首先,我們從我們在文件開頭定義的JawboneAuth對象設置了我們的clientID,clientsecret,授權庫,tokenurl和callbackurl。這是使用新的JawboneStrategy()。

bodyParser <span>= require('body-parser'),</span>
接下來,我們將擁有處理此數據的回調函數。我們在此回調函數中使用令牌和完成值。令牌是Jawbone UP API訪問令牌,我們需要將其與API的任何呼叫一起包括在內,以證明我們已對其進行了身份驗證。完成的是將我們的數據返回到應用程序的回調函數。

>

>我們將訪問令牌以及前面定義的客戶端ID和秘密傳遞到選項對像中的jawbone-up模塊:

>

<span>var express = require(‘express’),
</span>    app <span>= express(),</span>

Jawbone-UP模塊是節點模塊,它使我們訪問Jawbone UP API端點。這些是我們對API返回用戶數據的呼叫(例如獲取https://jawbone.com/nudge/api/v.1.1/users/@me/sleeps)這些在諸如up.moves.get()和up.sleeps .get()之類的函數中。在我們的示例中,我們將使用up.sleeps.get()獲取睡眠數據。

> 在UP.Sleeps.get()中,我們有兩個變量,分別是錯誤和身體。如果從API接收數據時存在錯誤,則將其返回在ERR變量中,因此我們在回調開始時對此進行測試。

>

>否則,我們將數據返回到身體變量中的JSON字符串中。車身變量將包含一個看起來像這樣的值的json字符串:

>

ejs <span>= require('ejs'),</span>
我們想要的一切都在數據中。 我們使用json.parse(body)將上面的值解析到JavaScript對像中,並將數據鍵中的值分配給一個稱為JawboneData的變量:>

然後,我們有一個用於循環的循環,可以通過數據中的每個項目,並格式化我們的日期和睡眠時間,然後再將它們返回我們的模板以顯示。

https <span>= require('https'),</span>
在這裡,我們在日期中閱讀,將其轉換為字符串,然後將我們自己分開。它作為20150408的價值返回,因此我們將前四位數字歸為一年,在那個月之後的兩個數字,而最後兩個人則是一天。然後,我們安排它,以便它將是DD/mm/yyyy,如果您希望以美國日期格式格式化,則可以切換一個月:

>

fs <span>= require('fs'),</span>
jawbone api返回一個相對良好格式的睡眠持續時間值,就像這樣的標題:“對於9h 43m”。我們可以使用它,但要刪除“ for”部分,例如:

>

然後,我們將數據返回到我們的護照的回調功能,該回調功能將呈現我們的userData.ejs。為此,我們將JawboneData變量返回到完成的功能。還有一個控制台。 log只是為了顯示顯示jawbone up數據以顯示以下顯示:>>>>
bodyParser <span>= require('body-parser'),</span>

使用https

正如我之前提到的,為了使用Jawbone UP API,我們需要使用HTTPS運行服務器,因為Jawbone的服務要求雙方運行HTTPS。如果未設置為https的callbackurl,當您嘗試登錄時,您將收到“無效的重定向”錯誤。
passport <span>= require('passport'),
</span><span>JawboneStrategy = require('passport-oauth').<span>OAuth2Strategy</span>,</span>
為了使我們的示例工作,我們將使用自簽名的證書。如果您在實時網站上進行此操作,則需要從有效的證書授權書中獲得適當的證書。

>在server.js中,我們定義了兩個SSL選項:>

port <span>= 5000,</span>
這些是我們兩個與身份驗證相關的文件的服務器上的文件位置:>
  • 鍵 - 這是我們服務器的私鑰
  • >
  • 證書 - 這是我們的自我簽名證書
  • >

>為我們的服務器生成一個私鑰

為了生成一個私鑰,我們需要使用OpenSSL工具包。 MAC OSX和Linux用戶應該已預裝。對於Windows用戶,您可以安裝Cygwin,在“選擇軟件包”屏幕上搜索“ OpenSSL”,然後選擇出現的軟件包。

>我們可以通過打開終端,導航到服務器的文件夾並運行以下命令來生成該私鑰:>

這將生成一個專用服務器密鑰,準備使用稱為server.key。

<span>var express = require(‘express’),
</span>    app <span>= express(),</span>
生成證書籤名請求(CSR)

然後,我們需要生成CSR。這通常會被發送給證書授權,但在我們的情況下,我們將自己簽署以進行測試目的。

>要使用上面創建的私鑰生成CSR,請運行以下命令:>

>您將獲得一個問題列表以回答,回答這些問題,您將收到CSR作為一個名為server.csr。

的文件。

使用我們的服務器私鑰

生成簽名的證書
ejs <span>= require('ejs'),</span>
>最後,要生成一個沒有證書授權的自簽名證書,我們運行以下命令,以生成一年有效的證書:

該命令應該已經生成了一個server.crt文件 - 這是您的證書。

刪除我們的證書請求

對於那些喜歡保持整潔和自我簽名證書的人,我們可以刪除server.csr。
https <span>= require('https'),</span>
我們是https就緒

>使用我們的私鑰和證書準備並在我們的節點文件中定義,我們的服務器可以作為HTTPS運行。以下代碼使用https和我們的ssloptions啟動了服務器:>

我們的EJS文件

該應用程序的HTML都在.ejs文件中,因此我們可以在需要時在其中包含JavaScript變量。這些文件都在 /視圖中。 index.ejs非常簡單,只包含一個標題,說明和登錄按鈕,該按鈕將轉到 /登錄 /jawbone:

> userdata.ejs是操作所在的地方。我們可以關注的主要位置是我們的桌子:

對於EJ的新手,我們將JavaScript嵌入標籤中。 我們將項目傳遞給UserData模板,我們通過使用for for so to to s o:。 然後,使用和將每個日期和標題插入我們的HTML。
fs <span>= require('fs'),</span>
我們的應用程序在行動

>要運行應用程序,前往您的終端並運行:>

>運行它,請訪問http:// localhost:5000,您會看到我們的初始頁面:
bodyParser <span>= require('body-parser'),</span>

如果我們單擊“登錄”按鈕,我們將被帶到http:// localhost:5000/login/jawbone,這將引導我們進入Jawbone UP Authentication Page。該頁面將提示我們獲取Jawbone登錄詳細信息。輸入這些詳細信息後,或者您已經登錄了Jawbone站點,您將被指示到驗證頁面,要求訪問用戶數據。單擊“同意”:
使用Node.js連接到Jawbone UP API

>

當我們單擊同意時,我們應該將其定向到http:// localhost:5000/sleepdata頁面,帶有我們的睡眠數據表:
使用Node.js連接到Jawbone UP API

>,如果我們單擊“註銷”按鈕,它應該登錄我們並將我們重定向回主頁。

結論

>完成了我們連接到Jawbone UP API並將數據返回到節點服務器的基礎的概述。 >

>從這裡開始的下一步可能包括設置數據庫以存儲數據以備將來使用,為應用程序創建用戶帳戶,擴展您從UP API中獲取的數據量,更改其顯示的方式(也許添加了一些漂亮的圖!)等等。將這些數據與許多其他API結合在一起,並且某些真正整潔的應用程序的可能性很大! >

其他有用的資源

節點 - jawbone-up模塊的文檔

jawbone開發人員文檔
    PASSPORT的文檔
  • 帶有用戶帳戶和mongodb
  • 的UP和節點演示
  • 經常詢問有關將jawbone UP API與node.js >什麼是Jawbone UP API,它是如何工作的?
  • > jawbone UP API是Jawbone提供的一組編程接口,允許開發人員與Jawbone up數據進行交互。它可以從Jawbone UP平台中提取數據,其中包括用戶的活動,睡眠,餐和其他與健康相關的數據。 API使用RESTFUL的呼叫和響應在JSON中格式化。

>如何將Jawbone UP API連接到Node.js?

將JAWBONE UP API與Node.js連接,您需要首先在Jawbone的開發人員網站上註冊您的申請,以獲取客戶ID和客戶端的秘密。然後,您可以在node.js應用程序中使用“ jawbone-up” npm軟件包。該軟件包提供了一種簡單的方法來驗證和向jawbone up api提出請求。

>由於jawbone停止了服務,您可能想考慮使用Jawbone UP API的替代方法?諸如Fitbit API,Google Fit API或Apple HealthKit之類的替代方案。這些API還提供了訪問用戶的健康和健身數據的訪問權限,並提供了廣泛的文檔來幫助開發人員。

> Jawbone及其服務發生了什麼?該公司已過渡到稱為Jawbone Health Hub的醫療訂閱服務。但是,不再支持Jawbone UP應用程序和API。可用的。使用此API的任何應用都將不再按預期運行。建議切換到替代API以訪問健康和健身數據。

>

>如何從Jawbone UP API遷移到Fitbit API?

>從Jawbone UP API遷移到Fitbit API涉及幾步。首先,您需要在Fitbit的開發人員網站上註冊您的應用程序。然後,您可以使用Fitbit API訪問用戶的健康和健身數據。 FITBIT API提供了與Jawbone UP API相似的功能,包括訪問活動,睡眠和餐數據。

>

什麼是node.js,為什麼它用於與APIS連接? Node.js是基於Chrome的V8 JavaScript引擎的JavaScript運行時。它用於構建可擴展網絡應用程序。 Node.js是非阻滯,它使其高效且輕巧,非常適合數據密集型實時應用程序。由於其效率和易用性,通常用於與API連接。

>

>在使用node.js? ​​連接到帶有節點的API時,我該如何處理錯誤.js,您可以使用“錯誤”事件處理錯誤。每當請求期間發生錯誤時,就會發出此事件。您可以聆聽此事件並適當處理錯誤,例如記錄錯誤或重試請求。

>

我可以使用Fitness Tracker API訪問哪些數據?訪問一系列健康和健身數據。這包括活動數據(如台階,距離和燃燒的卡路里),睡眠數據(例如睡眠時間和睡眠質量)以及進餐數據(例如食物攝入和營養信息)。可用的確切數據取決於特定的API和用戶授予的權限。

>

>在使用健身跟踪器API時如何確保用戶數據的隱私和安全性? API,重要的是要遵循數據隱私和安全性的最佳實踐。這包括在訪問數據之前,使用安全連接(HTTP)在所有請求中獲得用戶同意,安全地存儲用戶數據,並僅請求您的應用程序所需的最小數據。

以上是使用Node.js連接到Jawbone UP API的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
從網站到應用程序:JavaScript的不同應用從網站到應用程序:JavaScript的不同應用Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python vs. JavaScript:比較用例和應用程序Python vs. JavaScript:比較用例和應用程序Apr 21, 2025 am 12:01 AM

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C/C在JavaScript口譯員和編譯器中的作用C/C在JavaScript口譯員和編譯器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具