笔记
0工具
0此页用于记录用户反馈问题后的每一次改进
关于
“写笔记”支持四种格式——Word 文档、Excel 表格、Markdown、纯文本,起稿或二次编辑时都能随时切换,同一篇笔记想用哪种形态来记,都由你说了算。
md、txt、csv、json 这类纯文本则原样载入,不做多余加工。拿一张现成的表倒进来、改几笔、再导出去,等于白用一台免费的格式转换器。
要带走就在右上角点“下载”,可导出 PDF、Word、Markdown、Excel、TXT 等格式;列表卡片“⋯”菜单里,也有同样的下载入口。
在“工具”页点“+ 上传工具”即可发布:填好名称与链接,再用 Markdown 把使用方法写清楚——能解决什么问题、怎么装、怎么用,比堆介绍实在。
要分发安装包就一并上传压缩包(ZIP、RAR、7Z、TAR.GZ,最大 35MB),别人在详情页一键下载;只放链接不带附件也可以。
工具按大家的收藏热度排序,好用的自然会被顶上来。发布后可在详情页或卡片菜单里编辑、下架。
写笔记时勾上“隐藏”,这篇就只存在于你自己的账号里:不进列表、不进搜索、不上首页精选,也不会出现在任何公开的页面,链接发给别人同样打不开。
适合放密码、草稿、日记这类只给自己看的内容;想公开,去“发布”打开它,把“隐藏”的勾去掉再保存,之后编辑会默认保持原状态,不会悄悄变回公开。
不想公开、只想临时给人看:点“分享”生成一条带密码和有效期的链接,到期自动失效,你也能随时撤销。
你的内容会同时保存在多个副本上,系统定期做备份与完整性校验,再配合异地容灾机制:就算某台机器出问题,数据也不会丢,可以长期放心存放;特别重要的资料,仍建议你另外再留一份备份。
全站跑在容器化、模块化的现代架构上,更新、部署、回滚都很快,扩展性和稳定性都按长期运营的标准来设计(Built for reliability, designed to scale)。
这个网站最早只是一个人的笔记仓库,后来慢慢长成现在的知识中枢。设计上很克制——没有广告、没有追踪、没有推荐算法,只是干干净净地存放一些东西;既然做好了,就公开出来,万一有人用得上呢。
不做大而全,不做平台梦,保持简单、保持克制、保持好奇。所有内容都由用户贡献、由用户维护:不会突然冒出付费墙,不会在角落塞广告位,也不会把你的数据卖给第三方。
产品会持续迭代,站内日志页记录着每一次改动,改了什么都有迹可循;想了解这个站是怎么一步步走到今天的,翻翻日志就能看到来龙去脉。
如果在这里看到涉嫌违规的内容,点对应卡片右侧的“举报”按钮就能提交,我们会尽快核实处理;也谢谢你花一点时间,一起把这里维护干净。
趋势
全新的HTTP QUERY方法
如果你曾经构建过搜索接口,一定遇到过这个困境。你的查询条件包含筛选器、排序规则、一组嵌套的分面(facets),可能还有个地理边界框。这些内容塞不进URL,硬塞进查询字符串参数又丑又脆弱。于是你只好用POST /search,把整个查询体塞进JSON,然后默默接受一个事实:你刚刚在请求语义上撒了谎。这个请求不是在创建任何东西,它是个读操作。但POST是唯一允许你附加请求体而不跟平台打架的工具。这个缺口终于被填补了。2026年6月,IETF发布了RFC 10008,定义了HTTP QUERY方法:一个专门为这种场景设计的新动词。
两个糟糕的选择
每个需要结构化输入的读操作都曾在GET和POST之间左右为难,而这两种选择各有各的问题。
GET在语义上是正确的选择。它是安全的(客户端没有要求修改任何东西)、幂等的(重试没问题),而且可以缓存。问题出在请求体上。RFC 9110明确指出,GET请求中的内容没有定义的语义,发送带有请求体的GET请求可能导致某些实现直接拒绝。所以你的查询条件只能放在URI里,然后就会遇到各种问题:代理服务器和服务器之间未知的长度限制、编码开销、查询条件暴露在访问日志和浏览器历史记录中。
POST解决了请求体的问题,却带来了新问题。它可以携带任意载荷,但根据定义它既不安全也不幂等。中间件不会缓存它,客户端在连接断开后不会自动重试,任何检查流量的组件都必须假设这个请求可能有副作用。你得到了请求体,却失去了让请求变得"诚实"的一切特性。
QUERY就是缺失的第三个选项:一个既能携带请求体、又能保持读操作语义的方法。
QUERY到底是什么
这个规范由Julian Reschke、James Snell和Mike Bishop共同编写,用一句话概括就是:QUERY请求要求目标处理包含的内容,以安全和幂等的方式,然后返回处理结果。
一个QUERY请求看起来像这样:
QUERY /products HTTP/1.1
Host: example.com
Content-Type: application/json
Accept: application/json
{
"filters": {
"category": "keyboards",
"inStock": true
},
"sort": [{"field": "price", "order": "asc"}],
"page": {"size": 20}
}
三个关键特性:
它是安全和幂等的。 客户端不是在请求状态变更,请求可以重试或重复执行,不用担心部分副作用。这是POST永远无法保证的。
它是可缓存的。 缓存可以存储响应,并用它来满足后续的QUERY请求。需要注意的是,缓存键必须包含请求内容,而不仅仅是URI,因为请求体才是区分不同查询的关键。两个发送到同一个URL但请求体不同的QUERY请求,被视为不同的请求。
响应不是URI的表示。 与GET不同,GET返回的是该URL对应的资源;QUERY响应是你在目标范围内运行查询得到的结果。GET /products返回products资源;QUERY /products返回你从该资源中筛选出的内容。
那些需要注意的细节
在你开始实现之前,有几个规则值得了解。
Content-Type是必须的。 如果请求头缺少Content-Type字段,或者内容类型与请求体不一致,服务器必须拒绝这个请求。实践中,缺少媒体类型会返回400,服务器不支持的媒体类型会返回415 Unsupported Media Type,请求体解析成功但内容不是有效的查询时返回422 Unprocessable Content。
有两个响应头容易让人混淆,因为它们听起来很像:
- Content-Location指向代表这次查询结果的资源。客户端之后可以通过GET这个URL来获取相同的结果。
- Location指向代表查询本身的资源。客户端可以通过GET这个URL来重新执行查询,而不需要重新发送请求体。这对于把复杂的查询变成可分享的链接非常有用。
简单来说,Results指向答案,Location指向问题。
规范还建议你不要使用HTTP范围请求来做分页。 范围语义在技术上可以用,但大多数查询格式已经内置了自己的分页机制(比如SQL的FETCH FIRST),你应该使用这个机制。
现在能用HTTP QUERY吗?
客户端方面,已经可以用了。 Fetch API和axios这类库都接受任意的HTTP方法字符串,所以你现在就可以发送一个:
const res = await fetch("/products", {
method: "QUERY",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
filters: { category: "keyboards" }
}),
});
瓶颈在堆栈的其他地方。 QUERY不是CORS白名单方法,所以跨域的QUERY请求会触发预检OPTIONS请求。你的服务器必须返回Access-Control-Allow-Methods: QUERY,否则浏览器会阻止真正的请求。任何对方法进行白名单检查的组件都会拒绝QUERY,直到你告诉它放行:反向代理、WAF、API网关、nginx的limit_except块等等。方法在网络上传输是最容易的部分,真正花时间的是保护网络的配置。
框架和服务器的支持还在陆续落地。 新的HTTP方法不常出现。上一次大多数人接触的新方法是2010年的PATCH,所以生态系统的演进速度很慢。预计未来一两年内,原生路由辅助函数和中间件会逐渐填补这个空白,而不是一夜之间全部到位。
应该急着切换到QUERY吗?
大概不需要,也没有必要。你的POST /search端点还能工作,也不会消失。QUERY是更正确的工具,但不是紧急的迁移任务。
它真正提供的是对我们多年来一直用临时方案解决的问题的一个正式答案。当你设计一个新的需要结构化请求体的读端点时,你现在有了一个方法,它能准确表达你的意图:这是一个安全的、可重复的、可缓存的读操作,查询条件就在请求体里,位置恰当。即使旧的端点保持不变,在你下一个项目中也值得使用它。