今日已更新 498 条资讯 | 累计 20470 条内容
关于我们

标签:#JavaScript

找到 553 篇相关文章

AI 资讯

From Axios to alova: how we cut 80 lines to 5

Frontend request code often involves repetitive state management. This article compares Axios and alova through a paginated list example, analyzing how request strategization reduces boilerplate and when it's a good fit. The Pattern: Paginated List in Two Ways A common requirement: fetch a user list with pagination. Approach 1: Axios const [ data , setData ] = useState ([]); const [ page , setPage ] = useState ( 1 ); const [ total , setTotal ] = useState ( 0 ); const [ loading , setLoading ] = useState ( false ); const [ error , setError ] = useState ( null ); const fetchUsers = async ( currentPage ) => { setLoading ( true ); setError ( null ); try { const res = await axios . get ( ' /api/users ' , { params : { page : currentPage , pageSize : 10 }, }); setData ( res . data . list ); setTotal ( res . data . total ); } catch ( e ) { setError ( e . message ); } finally { setLoading ( false ); } }; useEffect (() => { fetchUsers ( page ); }, [ page ]); This pattern appears in nearly every data-fetching component. The actual business logic — GET /api/users — occupies a single line. The rest is infrastructure: state declarations, loading toggles, error handling, and effect management. Approach 2: alova with usePagination const { data , total , loading , error , page , pageSize , nextPage , prevPage , } = usePagination ( ( page , pageSize ) => alovaInstance . Get ( ' /api/users ' , { params : { page , pageSize }, }), { page : 1 , pageSize : 10 } ); Both implementations are functionally identical. The key difference is where the state management logic lives: in the component (Axios) vs. inside the hook (alova). What Changed Component of Axios version Handled by alova loading state + toggling Managed internally by usePagination error state + try/catch Managed internally by usePagination data state + assignment Returned as reactive value page state + change handler Built-in nextPage / prevPage total state extraction Extracted from response automatically useEffect dependency tr

2026-06-01 原文 →
AI 资讯

Error: Cannot Set Headers After They Are Sent to the Client

Error: Cannot Set Headers After They Are Sent to the Client If you've built APIs with Express for any length of time, you've probably seen this error: Error [ ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client Or: Cannot set headers after they are sent to the client The frustrating part is that the application often works for some requests and fails only under specific conditions. This error is almost always caused by sending multiple responses for the same request. Let's break down why it happens and how to prevent it in production code. Problem Consider this Express route: app . get ( " /users/:id " , ( req , res ) => { if ( ! req . params . id ) { res . status ( 400 ). json ({ error : " User ID required " }); } res . json ({ id : req . params . id }); }); Looks harmless. But if the first response is sent, Express continues executing the remaining code. Result: Error [ ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client The server attempts to send two responses for a single request. HTTP doesn't allow that. Why It Happens A request can only receive one response. Once Express sends: res . send (); or res . json (); or res . redirect (); or res . end (); the HTTP headers are already transmitted. Any attempt to modify headers or send another response will trigger the error. In production systems, this usually happens because of: Missing return statements Multiple async operations Duplicate error handling Middleware issues Promise and callback mixing Race conditions Example Missing Return Statement This is the most common cause. app . get ( " /profile " , ( req , res ) => { if ( ! req . user ) { res . status ( 401 ). json ({ error : " Unauthorized " }); } res . json ( req . user ); }); If req.user is missing: res . status ( 401 ). json (...) runs first. Then: res . json ( req . user ) runs immediately afterward. Two responses. One request. Crash. Correct Version app . get ( " /profile " , ( req , res ) => { if ( ! req

2026-06-01 原文 →
AI 资讯

JWT Explained: What's Actually Inside That Token (with a free decoder)

If you've ever worked with auth, you've seen a JWT — a long string like eyJhbGci... split into three parts by dots. It looks cryptic, but it's surprisingly simple once you see inside. A JWT has three parts header.payload.signature Header – tells you the signing algorithm, e.g. {"alg":"HS256","typ":"JWT"} Payload – the claims (the actual data), e.g. {"sub":"123","name":"John","iat":1516239022} Signature – verifies the token wasn't tampered with (needs the secret/key) The header and payload are just Base64url-encoded JSON — not encrypted. That means anyone can read them. So: ⚠️ Never put secrets in a JWT payload. It's signed, not hidden. Decoding one yourself You can decode the payload in the browser console: const [, payload ] = token . split ( " . " ); console . log ( JSON . parse ( atob ( payload ))); Or, if you just want to paste a token and instantly see the header + payload (without sending it to a server), I built a free decoder that runs entirely in your browser: https://forgly.dev/tools/jwt-decoder Decoding ≠ verifying Reading a JWT is trivial. Trusting it is not — you must verify the signature on your server with the secret/public key before relying on any claim. Decoding just lets you inspect what's there. That's the whole mental model: a JWT is a readable, signed envelope — not a locked box.

2026-05-31 原文 →
开源项目

🔥 SandeepVashishtha / Eventra - Eventra is a comprehensive event management system that empo

GitHub热门项目 | Eventra is a comprehensive event management system that empowers organizers to create, manage, and track events seamlessly. Built with a modern tech stack featuring React frontend and Spring Boot backend, Eventra provides everything needed to run successful events from creation to post-event analytics. | Stars: 106 | 3 stars today | 语言: JavaScript

2026-05-31 原文 →
AI 资讯

How I Built a Live Football Platform That Doesn't Fall Apart Under Load

A walkthrough of the architecture decisions behind Flacron Gamezone a production full-stack app built with Next.js, Express, PostgreSQL, and Redis. When a client approached me to build a live football match discovery platform, the requirements sounded straightforward on the surface: show live scores, let users subscribe, handle authentication. But the moment you start thinking about how those pieces connect in production, straightforward gets complicated fast. This is the story of how I designed the backend for Flacron Gamezone — what decisions I made, why I made them, and what broke along the way. Table of Contents The Problem With "Just Building It" The Architecture: Four Distinct Layers Why This Matters to a Client The Bug That Taught Me Something Real The Full Stack at a Glance What I'd Do Differently The Problem With "Just Building It" The easiest version of this app is a single Express file: one route handler that queries the database, formats the data, and sends a response. I've seen this pattern in tutorials everywhere. It works for demos. It falls apart in production. The problems are predictable: you can't test business logic without hitting the database, a change in one feature quietly breaks another, and the moment a second developer joins the codebase, nobody knows where anything lives. I wanted to build something I could actually be proud to show an employer or a client. That meant committing to a proper layered architecture from day one, even on a project this size. The Architecture: Four Distinct Layers The entire Express backend is organized into four layers. Each layer has one job and talks only to the layer directly below it. Route → Controller → Service → Repository Here's what each one actually does. Routes are just maps. They declare that POST /api/v1/subscriptions exists, attach the auth middleware, and hand off to the controller. No logic lives here. Controllers handle the HTTP boundary. They extract data from req.body or req.params , call th

2026-05-31 原文 →
AI 资讯

How Zone01 Kisumu "Build from Scratch" Approach Transformed Me from a Framework User to a Problem Solver

The Moment I Realized I Didn't Really Know JavaScript I was 2 months into learning JavaScript. I could use .map(), .filter(), .reduce() like any bootcamp grad. I felt confident. Then my instructor asked me one question: "How does .reverse() actually work?" I froze. I had used it hundreds of times. But I had no idea what was happening inside. I was a user, not a builder. That was the day everything changed. The 01EDU Difference: Build Tools, Not Just Use Them Most coding courses teach you to use built-in methods. 01EDU does something different. They disable the built-in methods. Then they say: "Now build it yourself." No .split(). No .join(). No .indexOf(). No .slice(). Just you, a text editor, and your brain. What I Built in 2 Weeks (Without Using Built-ins) Here are the JavaScript methods I re-created from scratch: Method What I Learned abs() Math is logic, not magic multiply(), divide(), modulo() Arithmetic is repeated addition/subtraction indexOf(), lastIndexOf(), includes() Searching is just looping and comparing slice() Negative indexes count from the end reverse() Arrays and strings are both indexed collections join() Building strings step by step split() Parsing is character-by-character inspection round(), floor(), ceil(), trunc() Decimals are just numbers between whole numbers Each function took hours of thinking, failing, debugging, and finally — understanding. The Most Painful Lesson: Loops The first time I tried to build repeat() without using .repeat(), I wrote an infinite loop. My computer froze. I had to force restart. That failure taught me more than any working code ever could. I learned to trace each iteration mentally. I learned to check my exit conditions. I learned to respect the loop. You don't truly understand loops until you've crashed your computer with one. What 01EDU Taught Me That No Bootcamp Could I learned how computers think, not just how to write code When you build .split() from scratch, you understand string parsing at a deep level.

2026-05-31 原文 →
AI 资讯

Lottie JSON vs .lottie Format — What's the Difference and Which Should You Use?

Two file formats. Same animations. Very different performance characteristics. If you've used Lottie before, you know the .json file — you export it from After Effects with the Bodymovin plugin, drop it into lottie-web, done. But there's a newer format: .lottie. It's a binary container that replaces the JSON, and if you're starting a new project, it's worth understanding the difference. What is Lottie JSON? The original format. A .json file that describes vector animations: shapes, keyframes, layers, colors, timing. It's plain text, human-readable, and widely supported. Pros: Works everywhere Lottie is supported Human-readable (you can inspect and edit it) Supported by every tool and library Cons: Large files (uncompressed JSON with lots of repeated data) No built-in support for multiple animations in one file No metadata or preview image support What is .lottie? The .lottie format (sometimes called dotLottie) is a ZIP container with a .lottie extension. Inside it contains: The animation data (compressed JSON) A manifest.json describing the file Optional preview images Optional multiple animations in one container It was developed by LottieFiles and adopted as the preferred format for modern Lottie tooling. Pros: ~30-70% smaller than equivalent JSON (thanks to compression) Can contain multiple animations in one file Supports preview thumbnails Cleaner API in the @lottiefiles/dotlottie-web renderer Cons: Binary format — not human-readable Requires the dotLottie player (not the older lottie-web) Slightly less universal support File Size Comparison For a typical 2-second UI animation: Format Typical Size Lottie JSON (.json) 40 – 120 KB dotLottie (.lottie) 15 – 50 KB The size reduction comes from standard ZIP compression applied to the JSON content. It's meaningful on mobile connections. Converting Between Formats The easiest way to convert between .json and .lottie formats is using the free browser-based tools at IconKing . No signup required, no file size limits. Just

2026-05-31 原文 →
AI 资讯

SVG Icon Systems in 2025 — Everything You Need to Know

Every web app needs icons. How you manage them at scale — that's where most teams make mistakes. This is the complete guide to building an SVG icon system that doesn't fall apart as your app grows. Why SVG (Not Icon Fonts or PNG) Icon fonts (FontAwesome, etc.) are the legacy approach. The problems: One broken font file breaks all icons Accessibility is terrible (screen readers read the unicode character) Crispy rendering requires specific font-smoothing hacks No multi-color support PNG icons are dead for UI work. Blurry on Retina, can't be styled with CSS, fixed file per size. SVG wins: Infinitely scalable, pixel-perfect on any screen Styleable with CSS ( currentColor , fill, stroke) Accessible with proper ARIA labels Can animate with CSS or SMIL Single format handles all sizes Where to Get Free SVG Icons IconKing SVG Library — 254+ free SVG icons in flat and outline styles. Covers UI, social media, food, objects, and more. Downloadable as individual SVG, AI, or PNG files. No account required. What sets IconKing apart: many icons have matching animated Lottie versions in the Lottie library — useful when you want an animated hover state that matches your static icon. Other solid free sources: Heroicons (heroicons.com) — MIT, Tailwind-made, 292 icons Phosphor Icons (phosphoricons.com) — MIT, 1,248 icons, 6 weights Lucide (lucide.dev) — ISC, 1,400+ icons, React/Vue packages Tabler Icons (tabler.io/icons) — MIT, 5,000+ icons Method 1: Inline SVG Best for: small number of icons, need CSS styling <!-- Inline the SVG directly --> <button aria-label= "Close" > <svg width= "20" height= "20" viewBox= "0 0 24 24" fill= "none" stroke= "currentColor" stroke-width= "2" > <line x1= "18" y1= "6" x2= "6" y2= "18" /> <line x1= "6" y1= "6" x2= "18" y2= "18" /> </svg> </button> The stroke="currentColor" means the icon inherits its color from the parent element's CSS color property — trivial theming. Method 2: SVG Sprite Best for: many icons, better performance (single HTTP request) Bui

2026-05-31 原文 →
AI 资讯

Free Loading Animations for Web Apps — Lottie, GIF, and SVG Spinners (2025)

Loading states are one of the most overlooked parts of app UX. A bad spinner makes an app feel cheap. A good loading animation makes wait time feel intentional. Here's a curated list of free loading animations you can use right now, organized by format. Lottie Loading Animations (Best Quality) Lottie is the gold standard for loading animations in 2025. Files are small (5-30KB), resolution-independent, and perfectly smooth at any size. IconKing Free Lottie Loaders — 500+ free Lottie animations including dozens of loading spinners, progress indicators, and transition animations. Download as JSON, no account required. Preview any file before downloading at iconking.net/preview . Customize colors to match your brand at iconking.net/editor — swap any color in-browser. Implementation (React): import { useEffect , useRef } from ' react ' ; import lottie from ' lottie-web ' ; function Loader ({ size = 80 }) { const ref = useRef ( null ); useEffect (() => { const anim = lottie . loadAnimation ({ container : ref . current , renderer : ' svg ' , loop : true , autoplay : true , path : ' /animations/loader.json ' }); return () => anim . destroy (); }, []); return < div ref = { ref } style = { { width : size , height : size } } />; } Implementation (Vanilla JS): import lottie from ' lottie-web ' ; lottie . loadAnimation ({ container : document . getElementById ( ' loader ' ), renderer : ' svg ' , loop : true , autoplay : true , path : ' /animations/loader.json ' }); Convert Lottie Loaders to GIF Need the loading animation as a GIF for emails, Notion docs, or environments where you can't run JavaScript? Free Lottie to GIF Converter — upload your JSON, get a GIF. Browser-based, no signup. Other export formats available at iconking.net: Lottie to WebP — animated WebP, smaller than GIF Lottie to APNG — animated PNG with transparency Lottie to MP4 — for video embeds Lottie to WebM — transparent video Lottie to SVG — static frame as SVG CSS SVG Spinners (Zero Dependencies) For simple l

2026-05-31 原文 →
AI 资讯

How to Add Lottie Animations to Your Website (Free JSON Files Included)

Lottie animations are small, crisp, and interactive. This guide covers finding free animations through production-ready implementation. What Is Lottie? Lottie is a JSON-based animation format from Airbnb. After Effects animations are exported via Bodymovin as small JSON files (10-100KB), rendered by a lightweight JS library. Key advantages over GIF: 10-50x smaller file size Resolution independent vector quality on any screen Interactive — play, pause, seek, speed control Full alpha transparency — no halo effects Step 1: Get Free Lottie JSON Files IconKing Free Lottie Library — 500+ free animations: UI icons, loaders, flags, illustrations. No account needed. Preview any file first: iconking.net/preview — drag and drop to instantly see how it plays. Edit colors and speed: iconking.net/editor — swap colors, adjust timing, all in-browser. Step 2: Install lottie-web npm install lottie-web Or CDN: <script src= "https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.12.2/lottie.min.js" ></script> Step 3: Basic Implementation import lottie from ' lottie-web ' ; const animation = lottie . loadAnimation ({ container : document . getElementById ( ' lottie-container ' ), renderer : ' svg ' , loop : true , autoplay : true , path : ' /animations/my-animation.json ' }); Step 4: React Component import { useEffect , useRef } from ' react ' ; import lottie from ' lottie-web ' ; function LottieAnimation ({ src , loop = true , size = 200 }) { const ref = useRef ( null ); useEffect (() => { const anim = lottie . loadAnimation ({ container : ref . current , renderer : ' svg ' , loop , autoplay : true , path : src }); return () => anim . destroy (); }, [ src ]); return < div ref = { ref } style = { { width : size , height : size } } />; } Step 5: Playback Controls animation . play (); animation . pause (); animation . setSpeed ( 1.5 ); animation . goToAndStop ( 30 , true ); // frame 30 animation . playSegments ([ 0 , 60 ], true ); // frames 0-60 only animation . addEventListener ( ' complete

2026-05-31 原文 →
AI 资讯

Idempotency Keys: The One API Pattern That Prevents Duplicate Payments (and Worse)

You hit "Submit Order" and nothing happens. The spinner just spins. Is it processing? Did the request get lost? You click again. If the API on the other end does not implement idempotency, you just placed two orders. Maybe two charges to your card. This is a solved problem — and the solution is simpler than you think. What Is Idempotency? An operation is idempotent if doing it multiple times produces the same result as doing it once. GET requests are naturally idempotent — fetching a resource does not change it. DELETE is also idempotent in practice. The trouble is POST and PATCH : create an order twice, and you get two orders. An idempotency key is a client-generated unique identifier (usually a UUID) that you send with a mutating request. The server stores this key with the result. If the same key arrives again — whether due to a retry, a network blip, or an impatient user — the server returns the cached result instead of executing the operation again. Implementing Idempotency on the Server Here is a minimal Express implementation backed by Redis: const express = require ( " express " ); const redis = require ( " ioredis " ); const { v4 : uuidv4 } = require ( " uuid " ); const app = express (); const cache = new redis (); app . use ( express . json ()); // TTL for idempotency records: 24 hours const IDEMPOTENCY_TTL = 86400 ; async function idempotencyMiddleware ( req , res , next ) { const key = req . headers [ " idempotency-key " ]; if ( ! key ) return next (); // optional on GET/DELETE const cached = await cache . get ( `idem: ${ key } ` ); if ( cached ) { const { status , body } = JSON . parse ( cached ); return res . status ( status ). json ( body ); } // Intercept the response to cache it const originalJson = res . json . bind ( res ); res . json = async ( body ) => { if ( res . statusCode < 500 ) { await cache . setex ( `idem: ${ key } ` , IDEMPOTENCY_TTL , JSON . stringify ({ status : res . statusCode , body }) ); } return originalJson ( body ); }; next ();

2026-05-31 原文 →
AI 资讯

Streaming an LLM response, in 4 GIFs

We have watched tokens stream in from an LLM before where they appeared one at a time, like the model was typing. If you used the Anthropic SDK's .stream() method, it just worked and you probably never saw what was on the wire. This post will majorly focus on how a stream response works and how bugs are handled by SDK behind the hood. 1. Why Streaming exists To enable the streaming option we would need to make one change in the post request that is a single field "stream": true and it will change the response experience. Here are the pointers we take from the gif. The left side shows no streaming as the cursor blinks for 4 seconds then the whole response lands at once. The right side shows the streaming where the first word shows up in about 300 milliseconds. Words flow in as the model generates them. Both the sides have same model, same prompt, same total time it is just the right side started giving response almost 4 seconds earlier. The 4 seconds wait time for a full reply feels broken. A streamed reply that finishes in four seconds feels fast. Streaming doesn't make the model faster it makes the wait disappear. 2. What's on the wire When you set stream: true , the API stops sending a single JSON blob. It opens a persistent HTTP connection and pushes events down the line as the model generates them. The format is Server-Sent Events (SSE) a web standard. Any SSE debugger will read this stream. Here's what comes through: A few things to notice: The text lives in delta.text , nested inside content_block_delta events. Those are the events we should look after. stop_reason moved. In post 1 , we saw it right there in the response JSON. Here, it arrives at the very end inside a message_delta event, just before message_stop . If the loop bails out as soon as the text stops arriving we will never see it. Chunks don't line up with tokens or words. You might get "Hello" in one chunk and " world" in the next, or both in one. The network decides where the cuts happens and it

2026-05-31 原文 →
AI 资讯

The Bug That Passes Every Toolchain Check: Circular Dependencies in JavaScript

A circular dependency is one of the few bugs that passes every check your toolchain runs. TypeScript compiles it cleanly. The tests pass. The build succeeds. The app ships. And somewhere deep in your import graph, a developer is staring at a TypeError: X is not a constructor that disappears the moment they add a console.log . Here are the three patterns that create them, what Node.js, webpack, Rollup, and esbuild actually do with them — they don't solve the problem, they each make a different tradeoff — and how to stop them from forming. What a circular dependency actually is A circular dependency exists when module A imports from module B, which imports — directly or transitively — from module A. // user.service.ts import { formatUser } from ' ./user.utils ' ; // user.utils.ts import { UserService } from ' ./user.service ' ; // ← closes the loop Neither developer planned this. user.service.ts needed a formatter. user.utils.ts needed the service type for a helper added three sprints later. Nobody saw the cycle form — they just saw two reasonable imports. This is how every circular dependency is born: through incremental, individually sensible decisions. The 3 patterns that create them 1. Barrel files ( index.ts re-exports) Barrel files are the biggest source of accidental cycles in TypeScript projects. // features/user/index.ts — re-exports everything in the feature export { UserService } from ' ./user.service ' ; export { UserRepository } from ' ./user.repository ' ; export { UserController } from ' ./user.controller ' ; export { formatUser , validateUser } from ' ./user.utils ' ; Now every file in the user feature imports from ../user (the barrel) for cleaner paths. And any utility the barrel re-exports cannot safely import anything else from the barrel without creating a cycle. // user.utils.ts import { UserService } from ' ../user ' ; // ← imports the barrel // The barrel re-exports user.utils → user.utils imports the barrel → cycle Teams adopt barrel files for

2026-05-31 原文 →