我有一個在 node.js 中開發的網路應用程式,現在我開始使用電容器創建一個移動應用程式。在 Web 應用程式中,我使用把手來引數化視圖,然后使用 res.render() 為它們提供服務。使用電容器,似乎要進行的方法是預編譯視圖(模板和部分),只需對服務器進行 AJAX 呼叫以獲取資料,然后使用 Handlebars.template.view(data) 等創建 html。所以這么好!
對于開發階段,我在本地機器上運行 api 服務器。我一直在本地機器上使用自簽名 SSL 證書,在過去的幾個月里,在我之前將我自己的證書頒發機構的證書添加到我的 MacOS 機器上的鑰匙串中并接受開發之后,它沒有給我帶來任何麻煩服務器在瀏覽器中的自簽名證書。使用電容器,直接在 www 中組織網路資產并創建 index.html 檔案后,我開始使用 iOS 創建移動應用程式的程序:
npx 上限添加 iOS
打開 ios/App/App.xcworkspace
我發現 iOS 模擬器不喜歡使用自簽名證書從 https 服務器訪問任何內容,盡管我將證書頒發機構的證書添加到設備的 Settings->General->About->Certificate Trust Settings 并啟用了完整信任根證書(包括我的證書頒發機構證書的串列)。在為此苦苦掙扎了一段時間后,我決定將我的開發服務器作為 http 運行,至少最初是為了讓事情順利進行。它仍然沒有作業,我認為這是因為 CORS,所以我將這個中間件添加到我的應用程式堆疊中:
import cors from 'cors';
var corsOptions = {
origin: 'capacitor://localhost',
optionsSuccessStatus: 200
}
app.use(cors(corsOptions));
這似乎有效,雖然轉瞬即逝!這是一個簡單的 AJAX 請求,用于測驗是否可以從開發服務器檢索資料:
document.getElementById('test').addEventListener('click', event => {
console.log('test clicked');
console.log(`apiServer: ${apiServer}`);
$.ajax({
url: `${apiServer}/api/test`,
type: 'get',
data: {},
success: function (data) {
console.log(`/api/test`, data)
},
error: function (err) {
console.log(`error: `, err);
}
});
});
在服務器上,路由如下所示:
router.get('/api/test', function(req, res, next) {
res.send({
title: 'API Test',
apiResponse: 'success',
});
});
啟動 iOS 模擬器后,我通過“測驗”按鈕進入應用程式的主螢屏。當我第一次單擊它時,它作業正常。日志顯示:
?? [日志] - apiServer: http://192.168.1.101:3000
?? [日志] - /api/test {"title":"API Test","apiResponse":"success"}
但是,隨后的單擊會給出錯誤:
?? [日志] - apiServer: http://192.168.1.101:3000
?? [日志] - 錯誤:{"readyState":0,"status":0,"statusText":"error"}
我不確定為什么。我添加了第二個 API 測驗路由并在第二次單擊時點擊它,但仍然得到相同的錯誤。也就是說,第一個 GET 請求有效,后續請求無效。在服務器上,我可以看到它對第一個 GET 請求的回應狀態為 200,有時也對第二個 GET 請求(無論我擊中相同的測驗路由還是兩個不同的路由),但是,在 iOS 模擬器上只有第一次命中獲取資料,第二次導致錯誤。隨后的 GET 請求(第三個、第四個……)沒有被服務器注冊,模擬器繼續給出同樣的錯誤:
?? [日志] - apiServer: http://192.168.1.101:3000
?? [日志] - 錯誤:{"readyState":0,"status":0,"statusText":"error"}
我被卡住了,可以使用幫助。謝謝閱讀!
更新:我嘗試了各種應用程式傳輸安全設定,如 Stack Overflow 和 Apple 開發者論壇的各種討論中所推薦的,包括:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
并且,這些設定的各種組合:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
<key>NSAllowsArbitraryLoadsInWebContent</key><true/>
<key>NSAllowsLocalNetworking</key><true/>
<key>NSExceptionDomains</key>
<dict>
<key>192.168.1.101:3000</key>
<dict>
<key>NSIncludesSubdomains</key><true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key<true/>
<key>NSExceptionRequiresForwardSecrecy</key><true/>
</dict>
</dict>
</dict>
但似乎沒有任何幫助。令人驚訝的是,如果我將 NSAllowsArbitraryLoads 設定為 NO,并洗掉 ATS 中的所有其他鍵,則行為保持不變。也就是說,第一個 AJAX 請求成功,而隨后的 AJAX 請求不成功,并給出與之前相同的錯誤。Info.plist 中的 ATS 設定似乎無關緊要!
uj5u.com熱心網友回復:
這似乎不是訪問外部 API 服務器的權限問題。我將 AJAX 呼叫封裝在一個函式 makeRequest() 中,然后嘗試使用 setInterval() 重復執行它:
setInterval(() => { makeRequest(); }, 2000);
這有效:對 API 的重復 GET 請求(無論是在我的本地服務器上http://192.168.1.101:3000還是在外部可用的公共服務器上,例如https://emojihub.herokuapp.com/api/random)現在成功的。因此,單擊按鈕時似乎有一些東西干擾了 AJAX 請求:從不是第一次在模擬器加載應用程式時,而是在隨后的時間。然后我將 event.preventDefault() 添加到按鈕事件偵聽器的頂部,這已經解決了問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/464417.html
