尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗AccessScan is a free, automated accessibility checker for the EU Accessibility Act (EAA) and WCAG 2.x. It is a local-first tool: node server.js serves a self-contained web UI and JSON API bound to localhost. A public hosted instance is also maintained — a static frontend on Vercel proxies /api/* to a Render-hosted backend.
Honest disclaimer: automated scans detect roughly 30–57% of WCAG issues (per Deque's research). A clean scan is not a compliance guarantee, and EAA enforcement is live in the EU. Use AccessScan as a fast first pass; obtain a manual audit for real assurance.
addedRules, fixedRules, severityChanges)Requirements: Node.js >= 18.
npm install # installs deps + downloads Chromium (~170MB first time)
npm start # serves on http://localhost:3000
PORT overrides the port (default 3000); HOST overrides the bind address (default 127.0.0.1).npx playwright install chromium once.http://localhost:3000, paste a URL, scan. No accounts, no database, no tracking.All endpoints are JSON unless noted. Polling endpoints return the current scan state.
| Method | Path | Description |
|---|---|---|
POST | /api/scan | Body { "url": "https://…", "crawl": false, "maxPages": 5 } → 202 { id, status: "running" }. 429 if a scan is busy or rate-limited, 400 on invalid/private URL or non-numeric maxPages. maxPages is total pages including the submitted URL, clamped 1–10, default 6. |
GET | /api/scan/:id | { status, phase, result | error } |
GET | /api/scan/:id/export?format=html|json|pdf | Downloadable report (409 until the scan finishes) |
GET | /api/scans/:id/compare | Diff vs. most recent other finished scan of the same normalized URL (origin+pathname, query/hash ignored): { comparable, previousId, addedRules, fixedRules, severityChanges, totalsBefore, totalsAfter } or { comparable: false } |
GET | /api/health | { ok, busy, playwright } |
Rate limiting applies only to POST /api/scan (accepted scan creations). Polling (GET /api/scan/:id, exports, compare) is deliberately unlimited — one scan legitimately generates many polls.
429 with a Retry-After headerRATE_LIMIT_MAX, RATE_LIMIT_WINDOW_MS (ms), RATE_LIMIT_GLOBAL_MAXIn production the server runs with trust proxy = 2 (two hops: client → Vercel edge → Render load balancer), so req.ip resolves to the real client IP and buckets stay per-user. Known caveat: a direct-to-Render attacker could spoof X-Forwarded-For to rotate per-IP buckets, but the global cap still bounds total load.
| Variable | Default | Purpose |
|---|---|---|
PORT | 3000 | Port the Express server listens on |
HOST | 127.0.0.1 | Bind address. Render sets HOST=0.0.0.0; locally leave the default |
PROXY_SECRET | unset | Shared secret for the Vercel→Render proxy. When set, every request must carry a matching x-proxy-key header or it gets a bare 403 — the Render URL becomes unusable directly. GET /api/health is exempt (Render's health check can't send headers; it only returns {ok,busy,playwright}). Must be identical on Vercel and Render |
RATE_LIMIT_MAX | 10 | Accepted scans per IP per window |
RATE_LIMIT_WINDOW_MS | 600000 | Rate-limit window length (ms) |
RATE_LIMIT_GLOBAL_MAX | 60 | Accepted scans globally per window |
PROXY_SECRET and the RATE_LIMIT_* variables are unset locally, so node server.js dev is unaffected.
AccessScan is local-first by design — node server.js is meant to run on your own machine. The hosted public instance uses a split architecture because Playwright scans cannot run on Vercel serverless:
browser ──► Vercel (static frontend, deploy root = public/)
public/vercel.json rewrites /api/* → serverless function
public/api/index.js ── fetch + x-proxy-key: PROXY_SECRET ──►
Render (accessscan-9gcz.onrender.com, node server.js, HOST=0.0.0.0)
gated: all requests except GET /api/health require x-proxy-key
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗