跳到主要内容

web 访问网络

web 是 Alia 的标准库网络模块,提供 URL 解析、HTTP 客户端/服务端、MIME 类型查询等功能。

引入模块​

import 'web' as web ~ 导入为变量
import 'web' ~ 导入作用域

URL 工具​

urlParse​

解析 URL 字符串为结构化对象。

参数类型必填说明
第一位置参数String是需要解析的 URL 字符串

返回对象属性:

属性类型说明
protocolString协议,如 'https'
hostString主机名+端口,如 'example.com:8080'
hostnameString主机名,如 'example.com'
portNumber?端口号,无则为 null
pathnameString路径,如 '/path'
searchString?查询字符串,无则为 null
hashString?锚点,无则为 null
hrefString完整 URL
const parsed = web.urlParse 'https://example.com:8080/path?key=value#anchor'
parsed.protocol ~ 'https'
parsed.hostname ~ 'example.com'
parsed.port ~ 8080
parsed.pathname ~ '/path'
parsed.search ~ '?key=value'
parsed.hash ~ '#anchor'

urlBuild​

从结构化对象构建 URL 字符串。urlBuild 是 urlParse 的逆操作。

参数类型必填说明
第一位置参数Object是包含 URL 各部分的对象
const url = call web.urlBuild *[
protocol: 'https',
hostname: 'example.com',
port: 8080,
pathname: '/api',
search: '?q=alia'
]
~ 'https://example.com:8080/api?q=alia'

urlEncode / urlDecode​

对整个 URL 进行编码/解码(保留 ://、?、# 等 URL 保留字符)。

web.urlEncode 'https://example.com/路径'
~ 'https://example.com/%E8%B7%AF%E5%BE%84'

web.urlDecode 'https://example.com/%E8%B7%AF%E5%BE%84'
~ 'https://example.com/路径'

urlEncodeComponent / urlDecodeComponent​

对 URI 组件进行编码/解码(会编码所有特殊字符)。

web.urlEncodeComponent 'hello world'
~ 'hello%20world'

web.urlDecodeComponent 'hello%20world'
~ 'hello world'

MIME 类型​

mimeGet​

根据文件扩展名获取对应的 MIME 类型。

参数类型必填说明
第一位置参数String是文件扩展名(可带或不带 . 前缀)
web.mimeGet 'json' ~ 'application/json'
web.mimeGet '.html' ~ 'text/html'
web.mimeGet 'png' ~ 'image/png'
web.mimeGet 'xyz' ~ 'application/octet-stream' ~ 未知类型默认值

内置 MIME 映射表:

扩展名MIME 类型
html, htmtext/html
csstext/css
js, mjsapplication/javascript
jsonapplication/json
xmlapplication/xml
txttext/plain
csvtext/csv
pngimage/png
jpg, jpegimage/jpeg
gifimage/gif
svgimage/svg+xml
icoimage/x-icon
webpimage/webp
mp3audio/mpeg
wavaudio/wav
oggaudio/ogg
mp4video/mp4
webmvideo/webm
pdfapplication/pdf
zipapplication/zip
gzapplication/gzip
tarapplication/x-tar
wasmapplication/wasm
ttffont/ttf
wofffont/woff
woff2font/woff2
yaml, ymlapplication/x-yaml
mdtext/markdown

mimeGetExtension​

根据 MIME 类型获取首选文件扩展名。

参数类型必填说明
第一位置参数String是MIME 类型字符串
web.mimeGetExtension 'text/html' ~ 'html'
web.mimeGetExtension 'application/json' ~ 'json'
web.mimeGetExtension 'application/x-unknown' ~ null

HTTP 客户端​

httpRequest​

发起异步 HTTP 请求。

参数类型必填说明
第一位置参数Object是请求选项对象

请求选项对象属性:

属性类型必填默认值说明
urlString是-请求 URL
methodString否'GET'HTTP 方法
headersObject否{}请求头
bodyString否null请求体
timeoutNumber否30000超时时间(毫秒)

返回 Stack(异步请求对象,需 await 消费):

发起请求后返回符合 Alia 异步模型的可 await Stack。请求在后台线程执行,await 等待结果,响应对象可通过 task.response 访问。

属性类型说明
statusNumberHTTP 状态码
statusTextString状态文本
headersObject响应头
bodyString响应体
okBoolean状态码 200-299 时为 true
const opts = *[
method: 'GET',
url: 'https://api.example.com/data'
]
const resp = await web.httpRequest opts
if (resp.ok as Boolean) {
print resp.body as String
}

await 接受返回 Stack 的表达式,可一步到位取得响应;也可先持有任务句柄再等待,以便访问 isRunning/isDone/detach:

const task = web.httpRequest opts
await task
if (task.response.ok as Boolean) {
print task.response.body as String
}

在线检测​

推荐以 https://alia.0832.ink/externalAccess 静态探针判定在线:该文件部署于文档站,内容为 true。

import 'web' as web
const opts = *[url: 'https://alia.0832.ink/externalAccess', timeout: 10000]
const task = web.httpRequest opts
await task
assert (Ok task.response.body) error 'externalAccess should return body'
assert (call task.response.body.trim) == 'true' error 'externalAccess should be true'
assert task.response.status == 200 error 'externalAccess should return 200'

离线时请求失败/回退为 HTML,非 true。

serverCreate​

创建 HTTP 服务器实例。

const server = call web.serverCreate

返回 Server 对象方法:

server.addRoute​

注册路由处理函数。

参数类型必填说明
第一位置参数String是HTTP 方法(GET、POST 等)或 * 匹配所有
第二位置参数String是路径模式,支持 :param 动态参数
第三位置参数Alias是请求处理函数 (req, res) -> { ... }
server.addRoute 'GET' '/hello' (alias -> <Object req> and <Object res> {
res.send 'Hello, World!'
})

server.addRoute 'GET' '/users/:id' (alias -> <Object req> and <Object res> {
call res.json *[userId: (req.params as Object)['id']]
})

server.addRoute 'POST' '/api/data' (alias -> <Object req> and <Object res> {
~ req.body 包含请求体
call res.json *[received: true]
})

请求对象(req)属性:

属性类型说明
methodStringHTTP 方法
urlString原始 URL
pathString路径部分
queryObject查询参数
headersObject请求头
bodyString?请求体
paramsObject?路径参数

响应对象(res)方法:

方法说明
res.setStatus code设置状态码,默认 200
res.setHeader name value设置响应头
res.send bodyText发送文本响应
res.json data发送 JSON 响应(自动设 Content-Type)
res.end结束响应

server.listen​

启动服务器监听指定端口。

参数类型必填说明
第一位置参数Number是监听端口号
callbackAlias否启动成功后的回调
server.listen 3000 (alias -> {
io.print 'Server running on http://localhost:3000'
})

server.close​

关闭服务器(发起式、非阻塞:调用即发起关闭,端口资源异步释放)。

server.close

完整示例​

import 'web' as web
import 'io' as io

~ URL 解析
const parsed = web.urlParse 'https://example.com/search?q=alia'
print '主机: ' .. parsed.hostname
print '路径: ' .. parsed.pathname

~ HTTP 客户端(异步)
const opts = *[
url: 'https://api.github.com'
]
const task = web.httpRequest opts
await task
print '状态码: ' .. (task.response.status as Number)

~ HTTP 服务器
const server = call web.serverCreate

server.addRoute 'GET' '/api/hello' (alias -> <Object req> and <Object res> {
call res.json *[greeting: 'Hello from Alia!']
})

server.listen 3000
io.print '服务器已启动,访问 http://localhost:3000/api/hello'