Node18 即将支持 import HTTP资源!
作者 | 零一
來源 | 前端印象
最近看到Node官方提交了一條commit ,并且已經(jīng)合入 master分支 ,如下圖所示:
由此可見,Node18可能會(huì)支持一個(gè)非常 nice 的功能,那就是 支持 import 遠(yuǎn)程HTTPS資源和本地的HTTP資源,啥意思?看個(gè)例子🌰
嘗鮮
現(xiàn)在有這樣一個(gè)文件:
//?demo.mjs import?sayHelloWorld?from?"https://example/say-helloWorld.mjs";console.log(sayHelloWorld());可以看到,這里選擇加載了一個(gè)遠(yuǎn)程的HTTPS文件資源,該文件內(nèi)容如下:
//?say-helloWorld.mjs export?default?function?sayHelloWorld?()?{return?'Hello,World!?零一' }接下來運(yùn)行一下 demo.mjs看看會(huì)發(fā)生什么,因?yàn)樵贜ode18中,該功能屬于實(shí)驗(yàn)性功能,所以我們需要加上參數(shù) --experimental-network-imports 來啟動(dòng)該特性:
node?--experimental-network-imports?demo.mjs運(yùn)行結(jié)果:
// Hello,World!?零一當(dāng)然了,本地起的HTTP服務(wù)上的文件資源也是可以一樣導(dǎo)入的,例如:
import?sayHelloWorld?from?"http://10.59.24.2:8080/say-helloWorld.mjs"???//?ok注意
我們使用該特性導(dǎo)入的腳本資源文件有一個(gè)前提條件,那就是該文件所在的服務(wù)器上響應(yīng)此文件請(qǐng)求的類型 content_type 必須為 application/javascript,否則就無法加載
我們可以用 curl 來查看一下想要加載的文件響應(yīng)類型,例如:
$?curl?-s?-o?/dev/null?-w?'%{content_type}'?'https://example/say-helloWorld.mjs'#?application/javascript錯(cuò)誤場景
ERR_NETWORK_IMPORT_BAD_RESPONSE:當(dāng)導(dǎo)入的資源不存在時(shí),即響應(yīng) 404,就會(huì)報(bào)該錯(cuò)誤
Error?[ERR_NETWORK_IMPORT_BAD_RESPONSE]:?import?'https://xxxx/xxxx'?received?a?bad?response:?HTTP?response?returned?status?code?of?404ERR_NETWORK_IMPORT_DISALLOWED:當(dāng)請(qǐng)求一個(gè)HTTPS資源且被重定向到一個(gè)非網(wǎng)絡(luò)資源時(shí),是不被允許的
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:當(dāng)請(qǐng)求的資源不是 ESM 時(shí),會(huì)報(bào)該錯(cuò)誤
RangeError?[ERR_UNKNOWN_MODULE_FORMAT]:?Unknown?module?format:?null?for?URL?https://xxxxxx/say-helloWorld.jsERR_UNSUPPORTED_ESM_URL_SCHEME:當(dāng)加載的資源URL的協(xié)議不被支持時(shí),會(huì)報(bào)該錯(cuò)誤,例如 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:'實(shí)現(xiàn)原理
其實(shí)原理也比較簡單:
先調(diào)用 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); }若沒有緩存,則調(diào)用 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)?=>?{//?錯(cuò)誤檢查//?緩存內(nèi)容//?返回模塊內(nèi)容} }然后根據(jù)資源類型去調(diào)用不同的方法(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}); }總結(jié)
這個(gè)功能還是很香的,誰用誰知道,但目前有一些缺點(diǎn):
實(shí)驗(yàn)性功能,可能還會(huì)改動(dòng),而且使用需要加參數(shù) --experimental-network-imports
本地只支持 http,一旦涉及到 https 就很淡疼
該功能的代碼實(shí)現(xiàn)就限制死了只支持 http: 和 https:,其它一概不支持
希望本文對(duì)你們有所幫助~
往期推薦
Android 13 第一個(gè)開發(fā)者版本來了,網(wǎng)友直呼:Android 12 還沒玩透!
k8s集群居然可以圖形化安裝了?
使用這個(gè)庫,讓你的服務(wù)操作 Redis 速度飛起
將 k8s 制作成 3D 射擊游戲,好玩到停不下來
點(diǎn)分享
點(diǎn)收藏
點(diǎn)點(diǎn)贊
點(diǎn)在看
總結(jié)
以上是生活随笔為你收集整理的Node18 即将支持 import HTTP资源!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 李飞飞:阿里云数据库已做好全面服务政企市
- 下一篇: Haystack 太强了!存 2600