Node18 即将支持 import HTTP资源!
作者 | 零一
來源 | 前端印象
最近看到Node官方提交了一條commit ,并且已經合入 master分支 ,如下圖所示:
由此可見,Node18可能會支持一個非常 nice 的功能,那就是 支持 import 遠程HTTPS資源和本地的HTTP資源,啥意思?看個例子🌰
嘗鮮
現在有這樣一個文件:
//?demo.mjs import?sayHelloWorld?from?"https://example/say-helloWorld.mjs";console.log(sayHelloWorld());可以看到,這里選擇加載了一個遠程的HTTPS文件資源,該文件內容如下:
//?say-helloWorld.mjs export?default?function?sayHelloWorld?()?{return?'Hello,World!?零一' }接下來運行一下 demo.mjs看看會發生什么,因為在Node18中,該功能屬于實驗性功能,所以我們需要加上參數 --experimental-network-imports 來啟動該特性:
node?--experimental-network-imports?demo.mjs運行結果:
// Hello,World!?零一當然了,本地起的HTTP服務上的文件資源也是可以一樣導入的,例如:
import?sayHelloWorld?from?"http://10.59.24.2:8080/say-helloWorld.mjs"???//?ok注意
我們使用該特性導入的腳本資源文件有一個前提條件,那就是該文件所在的服務器上響應此文件請求的類型 content_type 必須為 application/javascript,否則就無法加載
我們可以用 curl 來查看一下想要加載的文件響應類型,例如:
$?curl?-s?-o?/dev/null?-w?'%{content_type}'?'https://example/say-helloWorld.mjs'#?application/javascript錯誤場景
ERR_NETWORK_IMPORT_BAD_RESPONSE:當導入的資源不存在時,即響應 404,就會報該錯誤
Error?[ERR_NETWORK_IMPORT_BAD_RESPONSE]:?import?'https://xxxx/xxxx'?received?a?bad?response:?HTTP?response?returned?status?code?of?404ERR_NETWORK_IMPORT_DISALLOWED:當請求一個HTTPS資源且被重定向到一個非網絡資源時,是不被允許的
Error?[ERR_NETWORK_IMPORT_DISALLOWED]:?import?of?'ftp://xxxxx/say-helloWorld.mjs'?by?'https://h3manth.com/foo.mjs'?is?not?support:?cannot?redirect?to?non-network?locationERR_UNKNOWN_MODULE_FORMAT:當請求的資源不是 ESM 時,會報該錯誤
RangeError?[ERR_UNKNOWN_MODULE_FORMAT]:?Unknown?module?format:?null?for?URL?https://xxxxxx/say-helloWorld.jsERR_UNSUPPORTED_ESM_URL_SCHEME:當加載的資源URL的協議不被支持時,會報該錯誤,例如 ftp:
Error?[ERR_UNSUPPORTED_ESM_URL_SCHEME]:?Only?URLs?with?a?scheme?in:?file,?data,?https,?http?are?supported?by?the?default?ESM?loader.?Received?protocol?'ftp:'實現原理
其實原理也比較簡單:
先調用 fetchModule 方法檢查資源模塊是否緩存過(cacheForGET)
function?fetchModule(parsed,?{?parentURL?})?{const?{?href?}?=?parsed;const?existing?=?cacheForGET.get(href);if?(existing)?{return?existing;}if?(parsed.protocol?===?'http:')?{return?PromisePrototypeThen(isLocalAddress(parsed.hostname),?(is)?=>?{//?Makes?few?checks?for?ERR_NETWORK_IMPORT_DISALLOWEDreturn?fetchWithRedirects(parsed);});}return?fetchWithRedirects(parsed); }若沒有緩存,則調用 fetchWithRedirects
function?fetchWithRedirects(parsed)?{const?existing?=?cacheForGET.get(parsed.href);if?(existing)?{return?existing;}const?handler?=?parsed.protocol?===?'http:'???HTTPGet?:?HTTPSGet;const?result?=?new?Promise((fulfill,?reject)?=>?{const?req?=?handler(parsed,?{headers:?{Accept:?'*/*'}}).on('error',?reject).on('response',?(res)?=>?{//?錯誤檢查//?緩存內容//?返回模塊內容} }然后根據資源類型去調用不同的方法(HTTPGet、HTTPSGet)
let?HTTPSAgent; function?HTTPSGet(url,?opts)?{const?https?=?require('https');?//?For?HTTPGet,?we?use?the?`http`?builtinHTTPSAgent???=?new?https.Agent({keepAlive:?true});return?https.get(url,?{agent:?HTTPSAgent,...opts}); }總結
這個功能還是很香的,誰用誰知道,但目前有一些缺點:
實驗性功能,可能還會改動,而且使用需要加參數 --experimental-network-imports
本地只支持 http,一旦涉及到 https 就很淡疼
該功能的代碼實現就限制死了只支持 http: 和 https:,其它一概不支持
希望本文對你們有所幫助~
往期推薦
Android 13 第一個開發者版本來了,網友直呼:Android 12 還沒玩透!
k8s集群居然可以圖形化安裝了?
使用這個庫,讓你的服務操作 Redis 速度飛起
將 k8s 制作成 3D 射擊游戲,好玩到停不下來
點分享
點收藏
點點贊
點在看
總結
以上是生活随笔為你收集整理的Node18 即将支持 import HTTP资源!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 李飞飞:阿里云数据库已做好全面服务政企市
- 下一篇: Haystack 太强了!存 2600