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

标签:#JavaScript

找到 1018 篇相关文章

开发者

JWT Authentication in Node.js: A Practical Guide (with Express)

Ever logged into an app, closed the tab, come back, and you're still logged in — no password needed? That's almost always JWT doing its job behind the scenes. JWT (JSON Web Token) is one of the most common ways to handle authentication in modern backends. But a lot of developers use it without really understanding what's happening — and that's exactly where security bugs sneak in. Let's fix that. By the end of this post you'll know what a JWT actually is, how to use it in a Node.js + Express app, and the mistakes that quietly break real apps. What is a JWT, really? A JWT is just a string with three parts , separated by dots: xxxxx.yyyyy.zzzzz │ │ │ header payload signature Header — says which algorithm signed the token (e.g. HS256 ). Payload — the actual data (like userId , role , and an expiry time). This is not encrypted — it's just Base64-encoded. Anyone can read it. Signature — a cryptographic stamp created using a secret only your server knows. This is what stops people from faking tokens. Want to see this for yourself? Paste any token into a free JWT decoder and you'll instantly see the header and payload. Notice you can read everything without the secret — that's the key lesson: never put passwords or sensitive data in a JWT payload. Creating a token (login) Install the library: npm install jsonwebtoken When a user logs in successfully, sign a token: import jwt from ' jsonwebtoken ' // On successful login: const token = jwt . sign ( { userId : user . _id , role : user . role }, // payload process . env . JWT_SECRET , // secret (keep it in .env!) { expiresIn : ' 7d ' } // auto-expiry ) res . json ({ token }) Three things to notice: Keep the payload small — just an id and role, not the whole user object. The secret lives in an environment variable, never hardcoded. Always set expiresIn . A token that never expires is a token that can be stolen forever. Verifying a token (protecting routes) Now create a middleware that checks the token on every protected request

2026-08-24 原文 →
AI 资讯

Building an ASCII Art Generator with AI: The Good, The Bad, and The Figlet

The Problem I was staring at my terminal during a deploy, waiting for the build to finish, when I realized something: I'd been typing figlet "Hello World" into my terminal for years to generate ASCII art for commit messages and README files. But every time I wanted to share that art with someone who wasn't a developer, I hit a wall. "Just install figlet," I'd say. "Install what now?" they'd reply. The problem wasn't that ASCII art tools don't exist online. The problem was that the ones I found were either bloated with ads, required JavaScript frameworks that made the page take forever to load, or couldn't handle non-Latin characters gracefully. I wanted something that just worked in a browser tab, no installation, no server, no fuss. So I decided to build my own. Because apparently I enjoy reinventing wheels. The AI-Assisted Development Journey Here's where things get interesting. I've been using AI pair programming for a while now, and this project felt like the perfect test case: it's well-defined, has clear requirements, and involves a lot of repetitive font data that would be tedious to type manually. The Initial Prompt I started by describing the requirements to an AI assistant in pretty specific terms: Build a single-file HTML tool that converts text to ASCII art. Must have multiple fonts (Block, Slant, Small, Standard, Mini). Real-time preview. Copy to clipboard. Download as .txt. Support dark mode. Chinese/English i18n. Vanilla JS only. The AI came back with something surprisingly decent. It had the basic structure right, the font data was embedded, and the rendering logic was clean. But there were issues. Where AI Got It Wrong The first problem was character handling . The AI assumed that all input would be uppercase English letters. When I tested with lowercase, numbers, and special characters, it just... broke. Not crashed, but silently dropped characters. // What the AI initially wrote (simplified) function getChar ( char , font ) { return font [ char .

2026-08-24 原文 →
AI 资讯

How to Build a Fair A/B Audio Preview for AI Processing

Two audio players do not make a fair before-and-after test. If the second player restarts from zero or takes half a second to load, the user is no longer comparing two versions of the same moment. They are comparing two memories. That is a weak way to evaluate any audio effect. It is especially weak for AI processing. A denoiser can remove a fan while softening consonants. A de-reverb model can reduce the room tail while making the voice sound less natural. The output may be cleaner without being better. The preview therefore has one job: let the listener switch quickly enough to hear both the improvement and the damage. The rule I use is deliberately boring. Both versions should contain the same edit and play from the same position. Switching should not restart playback or create a pause. The interface should not hint that one version is supposed to win. Two independent <audio> elements fail surprisingly quickly. Each owns its playback state, buffering behavior, clock, and seek operation. The user ends up finding the same position twice and comparing one sound with a memory of another. A better interface has one transport and one version control: [ Play ] [ Original | Processed ] 00:18 ━━━━━━━ 00:42 The transport decides where playback happens. The segmented control decides which signal is audible. One transport, two signals For a short preview, I decode both files into AudioBuffer s, start them at the same AudioContext time and offset, and route each through its own GainNode . Both sources run; only one gain is open. decodeAudioData() decodes complete file data and resamples it to the context's sample rate. The decoded buffers can then share the same audio clock. See the MDN documentation for format and loading details. The core is small: const context = new AudioContext (); const originalGain = context . createGain (); const processedGain = context . createGain (); originalGain . connect ( context . destination ); processedGain . connect ( context . destination )

2026-08-24 原文 →
AI 资讯

The Evolution of Web Forms — Part 3

The Evolution of Web Forms — Part 3: React Hook Form, Validation Libraries, and Zod In Part 2, we learned that React solved the problem of manually updating the DOM. Instead of writing: emailError . textContent = " Email already exists " ; emailInput . setAttribute ( " aria-invalid " , " true " ); React allowed us to describe the interface from state: < input aria-invalid = { Boolean ( errors . email ) } /> { errors . email && ( < p > { errors . email } </ p > )} However, React did not automatically manage: Form values Validation errors Touched fields Dirty fields Submission state Reset behavior Dynamic fields Backend errors Performance Developers still had to build those features manually. That created the need for form-management libraries. This part covers: React Hook Form’s philosophy and architecture React Hook Form’s core APIs Validation libraries React Hook Form with Zod and TypeScript By the end, we will build a production-style registration form using: React + TypeScript + React Hook Form + Zod + An API layer Stage 9: React Hook Form Deep Dive React Hook Form is not simply a shorter way to write controlled React forms. It uses a different architectural philosophy. A traditional controlled input stores its value in React state: const [ email , setEmail ] = useState ( "" ); < input value = { email } onChange = { ( event ) => { setEmail ( event . target . value ); } } /> Every keystroke produces a state update: User types ↓ onChange runs ↓ setEmail runs ↓ Component renders again ↓ Input receives the new value React Hook Form prefers native, uncontrolled inputs when possible. < input { ... register ( " email " ) } /> The browser stores the current value inside the input element. React Hook Form registers the input, listens to its events, tracks relevant form state, and reads its value when required. React Hook Form’s official documentation describes register() as the mechanism that connects an input to validation, value tracking, and submission. Controlled vers

2026-08-24 原文 →
AI 资讯

Your canvas.toBlob might be silently handing you a PNG

A user told me the .webp files my tool produced wouldn't open on their desktop. I opened one in a hex editor. First four bytes: 89 50 4E 47 . It was a PNG. With a .webp extension. The encoder wasn't broken. I had simply never checked whether the browser actually did what I asked. The spec says it's allowed to do this Here's the code. Nothing looks wrong with it: canvas . toBlob ( blob => { download ( blob , ' output.webp ' ); }, ' image/webp ' ); The callback fires. The blob isn't null. Its size looks reasonable. Everything succeeds — except it isn't WebP. This is not a bug. The HTML spec explicitly requires it: if the user agent doesn't support the requested type, it must create the file using the PNG format instead. No exception, no warning, no second argument telling you what happened. There's exactly one place that information exists — blob.type : canvas . toBlob ( blob => { console . log ( blob . type ); // iOS below 16.4: "image/png" }, ' image/webp ' ); toDataURL does the same thing, but at least there the fallback is visible to the naked eye, since the data URL literally starts with data:image/png;base64, . There is no capability query for this My first instinct was to special-case iOS. That falls apart quickly. Every browser on iOS is WebKit underneath, so "is this Safari" isn't a meaningful question. Embedded webviews inside apps track the system version in ways that don't always match the standalone browser. And a user can flip on "Request Desktop Website" and hand you a macOS user agent from an iPhone. More fundamentally: the user agent string answers "who are you" , and I need to know "can you encode WebP right now" . Between those two questions sit the engine version, OS version, host app, and build flags. Any mismatch in that chain and your lookup table lies to you. So I went looking for an official capability API. Media has them: MediaRecorder . isTypeSupported ( ' video/webm;codecs=vp9 ' ); // → boolean await navigator . mediaCapabilities . encoding

2026-08-24 原文 →
AI 资讯

How Particle Effects Improve Game Feel in HTML5 Games

A game can be mechanically correct and still feel flat. The button works. The enemy loses health. The coin counter increases. The level completes. Everything technically functions, but the player's actions do not seem to have much weight. Particle effects are one of the cheapest ways to fix that. Not because every screen needs fireworks, but because particles give actions a visible consequence. Feedback Should Happen Immediately Imagine tapping an enemy in a mobile game. Version A: tap enemy HP decreases Version B: tap small flash impact particles enemy reacts HP decreases The underlying mechanic is almost identical. The second version communicates the result more clearly. The player sees exactly where the hit happened. That matters on mobile screens where fingers frequently cover part of the action. Particles Can Explain the Game VFX is not only decoration. It can communicate state. Damage Particles show where an impact happened. Healing A slow upward effect can visually separate healing from damage. Selection A subtle glow or ring can show which object is active. Currency Particles moving toward a counter connect the collected object with the UI value that changed. Cooldowns A burst or dissolve can show that an ability has become available. Danger Smoke, sparks, or unstable energy can communicate that an object is close to breaking. Good VFX helps the player understand the game without another label or tutorial popup. Timing Matters More Than Particle Count A common mistake is assuming better effects need more particles. They usually need better timing. Consider a button press. You could emit 100 particles over two seconds. Or you could emit 12 particles exactly when the interaction occurs. The second effect will often feel better because it reinforces the player's action. For responsive games, the sequence might look like this: 0 ms input 0 ms visual response begins 20 ms burst expands 80 ms largest particles appear 200 ms effect begins disappearing 350 ms effect

2026-08-24 原文 →
AI 资讯

The Evolution of Web Forms — Part 1

The Evolution of Web Forms Part-1 — From Plain HTML to AJAX Modern React forms can feel unnecessarily complicated when you first encounter tools such as React Hook Form, Zod, resolvers, controlled inputs, refs, formState , and server-error handling. Why do we need all of that? Why not simply read the value from an input and send it to the server? To understand why modern form libraries exist, we need to understand the problems developers faced before those libraries were created. In this series, we will evolve the same idea step by step: Plain HTML ↓ Native HTML validation ↓ JavaScript validation ↓ AJAX submission ↓ React controlled forms ↓ Form libraries ↓ React Hook Form ↓ React Hook Form + Zod ↓ Production form architecture This first part covers the first four stages: Plain HTML forms Native HTML validation Vanilla JavaScript validation AJAX form submission By the end, you will understand how forms worked before React and why each new approach became necessary. Stage 1: Plain HTML Forms Before React, AJAX, or even large amounts of client-side JavaScript, browsers already knew how to submit forms. HTML forms are not just visual containers. They are a built-in browser mechanism for collecting data and sending an HTTP request. A basic registration form <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" /> <meta name= "viewport" content= "width=device-width, initial-scale=1.0" /> <title> Registration Form </title> </head> <body> <h1> Create an account </h1> <form action= "/register" method= "POST" > <div> <label for= "username" > Username </label> <input id= "username" name= "username" type= "text" /> </div> <div> <label for= "email" > Email </label> <input id= "email" name= "email" type= "email" /> </div> <div> <label for= "password" > Password </label> <input id= "password" name= "password" type= "password" /> </div> <button type= "submit" > Register </button> </form> </body> </html> There is no JavaScript in this example. The browser handles the ent

2026-08-24 原文 →
AI 资讯

🚀 From FlipaClip to SitePoint: The Full Story of Kehinde Owolabi

🚀 From FlipaClip to SitePoint: The Full Story of Kehinde Owolabi How a Nigerian teenager built a professional game engine with borrowed laptops, offline W3Schools, and pure determination. 🎮 Play the Game Try Limn Engine Live — Space Shooter Demo See what 4 years of determination built. This space shooter runs at 60 FPS on a Tecno Pop 4 with 1GB RAM. 📖 Introduction Every developer has an origin story. Some start with a fancy computer and a computer science degree. Others start with a flipbook app and a sister who trusted them with her phone. My name is Kehinde Owolabi . I'm 18 years old (born December 4, 2007), and I live in Lagos, Nigeria. I'm currently in PC103 at BYU Pathway, and I'm a member of The Church of Jesus Christ of Latter-day Saints. I built a 94/100 professional game engine called Limn Engine. It runs at 60 FPS on a Toshiba with 4GB RAM. It was published on SitePoint and ranked #3 among 2D JavaScript game engines. Nobody knew it was developed on a Chromebook, a borrowed Thinkpad (behind my sister's back), and a Toshiba that "hung like hell." That was the secret I kept for months. But that's only one part of this story. This is the full story of how I went from a button phone to a 94/100 game engine, from FlipaClip to SitePoint, from a boy who failed physics to a developer who built something that runs on a Tecno Pop 4. The one-line summary: "I'm Kehinde Owolabi, an 18-year-old developer from Lagos, Nigeria who went from FlipaClip to building a 94/100 game engine on borrowed laptops — and got published on SitePoint." 🎮🚀 🎨 The Beginning: FlipaClip and the Spark of Creativity Before I was a developer, I was an animator. I used FlipaClip — a simple animation app on mobile — to create flipbook-style animations. I loved bringing characters to life, frame by frame. I would spend hours drawing, tweaking, and watching my creations move. That creative spark stayed with me. I wanted to create interactive experiences. I wanted to build games. But I didn't know how.

2026-08-24 原文 →
开发者

How to Extract Colors From an Image Using JavaScript and Canvas?

How to Extract Colors From an Image Using JavaScript and Canvas Have you ever looked at an image and wanted to know the exact HEX color of a particular pixel? Designers often need to extract colors from photographs, screenshots, logos, UI designs, and illustrations. You can do this directly in the browser without uploading the image to a server. The browser Canvas API gives us everything we need. Reading pixels with Canvas The basic process is: Load an image. Draw it onto a canvas. Read the pixel data. Convert the RGBA values into a color format such as HEX or RGB. The important API is getImageData() . javascript const imageData = ctx.getImageData(x, y, 1, 1); const pixel = imageData.data; const r = pixel[0]; const g = pixel[1]; const b = pixel[2]; const a = pixel[3];

2026-08-24 原文 →
AI 资讯

Enforcing a style rule with a linter that actually fails the build

Background I run a fleet of static sites that publish new content every day, mostly unattended. One of the house style rules is simple: no emoji anywhere in our own copy. That rule is impossible to hold by hand. A single site builds a few hundred HTML files, and emoji can slip into nav icons, button labels, <title> , the RSS feed, or JSON-LD (the JSON-formatted metadata embedded in a page to describe its structure to search engines). Nobody is going to review all of that before every deploy. So I wrote emoji-lint , a check that exits 1 the moment it finds a single emoji . It sits in the pre-deploy gate, which means a failure stops that day's publish. This post is not about the regex. It's about what happens when you put a failing check into real operation: you immediately discover the places where the rule must not apply. How it works The core is unremarkable. A regex holds the emoji code point ranges, the scanner walks each file line by line, and matching lines are reported as JSON. const EMOJI_RE = / [\u {1F000}- \u {1FAFF} \u {2600}- \u {27BF} \u {2B00}- \u {2BFF} \u {1F1E6}- \u {1F1FF} \u {FE0F} \u {200D} \u {2049} \u {203C} \u {2122} \u {2139} ] /u ; \u{FE0F} (variation selector) and \u{200D} (ZWJ) are in there because emoji are not always a single code point. Arrows and similar symbols used in ordinary technical writing are deliberately left out. Catch everything and the check drowns in false positives, at which point people stop reading it. The interesting part came later. Three categories of content look exactly like a violation but must not be treated as one: Verbatim quotes from other people Real proper nouns whose official spelling contains a symbol Passages where the emoji itself is the subject being explained Delete the emoji in any of those and you break something more important than the style rule. One term up front: "masking" here means replacing a range with spaces so the scanner cannot see it. Nothing is deleted from the file. Implementation Scope

2026-08-24 原文 →
AI 资讯

App-like UX in Next.js 16.3

Building App-like Experiences with Next.js 16.3 A hands-on look at how Next.js 16.3 helps apps feel fast and smooth, more like a single-page app, without losing the benefits of server rendering. Using four demo apps, it shows how features like Instant Navigations, Cache Components, Partial Prefetching, optimistic updates, Suspense streaming, offline retry, and View Transitions work together in real apps ⚡️ Sponsor: Arcjet AI compliance controls Protect your AI applications from prompt injection, PII leaks, and unauthorized tool calls. 📙 Articles / Tutorials / News Next.js team AMA The Next.js team opened the floor to community questions and covered a lot of ground. The AMA focused on Next.js 16.3, performance, caching, App Router, React Server Components, and upgrading apps, along with some insight into how the team works on the framework Coordinating Optimistic Updates in Next.js This guide shows how useActionState and useOptimistic can work together to keep the UI updated right away, save changes in the right order, and roll back cleanly if something fails Using next/root-params in Next.js 16.3 The new next/root-params API lets Server Components read top-level params like [locale] from deep in the tree, which makes next-intl much easier to use Docs for React's new browser() API The docs for React's new browser() API are now available in Canary. You can pass it to use() , where it suspends to the nearest Suspense boundary on the server, then renders normally in the browser 📦 Projects / Packages / Tools Better Auth 1.7 A big release for Better Auth, especially around OAuth, OpenID Connect, SCIM, SSO, MCP, and device login flows. The main theme here is stronger auth, better enterprise identity support, and more standards-based ways for apps and devices to sign in and get access Next 16 Calendar "Flow" A calendar and booking demo exploring Async React, Cache Components, Partial Prefetching, and View Transitions with Next.js 16.3, React 19, Tailwind CSS v4, and Prisma.

2026-08-23 原文 →
AI 资讯

Knowing When to Use If/Else vs. Switch in JavaScript

If/else statements - We all know and love them. While they are incredibly powerful, there comes a point where a long chain of conditions only makes your code look messy. Choosing between if/else and switch depends on readability, but there's a hidden pro tip that makes switch much more powerful than many people think at first. Traditional Approach: If/Else Normally, we use if/else when our logic depends on complex ranges and multiple variables: // Hard to scan, bulky, and prone to typos let weatherAdvice = "" ; if ( temperature < 15 && isRaining ) { weatherAdvice = " Grab a heavy coat and an umbrella! 🌧️🧥 " ; } else if ( temperature < 15 && ! isRaining ) { weatherAdvice = " It's cold but dry. Just a jacket is fine! 🧥 " ; } else if ( temperature >= 15 && isRaining && isNightTime ) { weatherAdvice = " Warm, rainy night. Stay indoors if you can! 🌧️🌃 " ; } else if ( temperature >= 15 && isRaining && ! isNightTime ) { weatherAdvice = " Warm rain during the day. Don't forget your umbrella! 🌧️🌦️ " ; } else if ( temperature >= 30 && ! isRaining ) { weatherAdvice = " It's scorching hot! Stay hydrated! ☀️🥤 " ; } else { weatherAdvice = " Weather seems pleasant today! 😎 " ; } Pro Tip: Using switch(true) Many developers think you can only use switch when you're checking a single variable against fixed values. However, you can use a switch statement for complex ranges by passing the boolean value true into the switch condition. Here is a cleaner switch statement version of the above code block: // Much easier on the eyes let weatherAdvice = "" ; switch ( true ) { case ( temperature < 15 && isRaining ): weatherAdvice = " Grab a heavy coat and an umbrella! 🌧️🧥 " ; break ; case ( temperature < 15 && ! isRaining ): weatherAdvice = " It's cold but dry. Just a jacket is fine! 🧥 " ; break ; case ( temperature >= 15 && isRaining && isNightTime ): weatherAdvice = " Warm, rainy night. Stay indoors if you can! 🌧️🌃 " ; break ; case ( temperature >= 15 && isRaining && ! isNightTime ): weather

2026-08-23 原文 →
AI 资讯

I turned browser cookie counts into game currency - meet Crumbongo

Crumbongo started from a pretty stupid little question: What if the number of accessible cookies on the website you're visiting could become game currency? So I built it. Crumbongo is a tiny local Chrome game where you choose a website, let the extension count the accessible cookie records for that site, and turn only that number into game rewards. No cookie names or values are used for gameplay. From a tiny experiment to an actual little game The first version was basically: choose a website; check its accessible cookie count; harvest that number into a Cookie Jar; spend the cookies on Bongo. Then I kept building on top of it. Crumbongo now has: a level and progression system; pixel-art cosmetics; multiple habitats; companions; local statistics; Monkey Climb; Cookie Stack. The whole thing still lives inside a Chrome extension popup. The technical side Crumbongo is deliberately small. There is no React, TypeScript, Vite, game engine, backend or framework involved. It's built with: vanilla JavaScript; HTML; CSS; Chrome Extension APIs; requestAnimationFrame for the minigames; chrome.storage.local for persistent game progress. The minigames are built with regular DOM elements and CSS rather than Canvas. That constraint became part of the fun: figuring out how far I could push a tiny extension popup without turning the project into something much larger. Local by design Because the core mechanic involves browser cookies, I wanted the privacy model to be extremely clear. Crumbongo requests access one site at a time. For gameplay it only uses the number of accessible cookie records returned for that site. It does not: store or transmit cookie names; store or transmit cookie values; modify or delete browser cookies; use an account system; use analytics or tracking; send gameplay data to a backend. Game progress stays locally in the browser. The game-design part became more interesting than I expected Once I added progression, I realized the cookie mechanic could support mu

2026-08-23 原文 →
AI 资讯

Making webpack's Docs Update Themselves | GSoC 2026, wrapped

Contributor: Nikhil Kumar Rajak ( @ryzrr ) Organization: webpack · Project: webpack-doc-kit Mentors: Aviv Keller ( @avivkeller ), Claudio Wunder ( @ovflowd ), Sebastian Beltran ( @bjohansebas ) Teammates: Mohamed Shams El-Deen ( @moshams272 ), Tushar Thakur ( @TusharThakur04 ) Period: 25 May to 17 August 2026 The problem webpack's docs lived at webpack.js.org and every API change meant somebody updating them by hand. Pages go stale and nobody notices until a reader does. webpack-doc-kit fixes that. It takes webpack's TypeScript declarations, runs them through TypeDoc, hands the output to nodejs/doc-kit for linking and UI, and produces a site that regenerates itself. We split the work three ways. Shams took AST parsing and content, Tushar took routing and navigation and UI, and I took the operational side: how docs get generated on a release, versioned & deployed. My six deliverables were PR-based doc sync, release-aware doc generation, versioned output folders, a deployment pipeline, CI validation before merge, and README fetch automation. All six shipped. Merged PRs in webpack-doc-kit 31 Lines added / removed +1,959 / −1,419 Distinct files touched 89 First / last merge 28 May ( #110 ) / 14 Aug ( #241 ) Merged PRs in other repos 2 Upstream issue filed and fixed 1 Everything below is merged into main . Nothing is open or pending. The release pipeline webpack releases happen in webpack/webpack . The docs live in webpack/webpack-doc-kit . A release in one needs to produce updated docs in the other with nobody doing anything. #110 set up versions.json as the single source of truth everything downstream reads, plus the script that maintains it and the workflow that runs it. My mentor proposed an object schema with latest , label , major , exactVersion , commit and frozen per entry. Review cut it to a flat array of tag strings, because everything else is derivable from the semver string and position [0] with unshift() already tells you which is latest. Right call, and I d

2026-08-23 原文 →
AI 资讯

Why Fixed-Window Rate Limiters Fail (And How to Fix Them with Math)

If you’ve ever built an Express API, you’ve probably reached for standard rate-limiting middleware to protect your login or payment endpoints from DDoS and brute-force attacks. Under the hood, most simple limiters use a Fixed-Window Counter . It’s easy to write: count incoming requests, and once the minute rolls over, reset the counter to zero. However, from a security and algorithmic standpoint, Fixed-Window counters have a massive blind spot. The Boundary Vulnerability (The 2-Second Spike) Imagine your endpoint allows a maximum of 100 requests per minute , resetting every full minute on the clock ( :00 ). Here is how an attacker bypasses that limit without breaking your rules: At 12:00:59 , the attacker fires 100 requests. (Allowed: 100/100 used). At 12:01:00 , the clock resets your counter back to 0. At 12:01:01 , the attacker fires another 100 requests. (Allowed: 100/100 used). To your server code, everything looks fine. But in reality, 200 requests slammed your backend within a 2-second window. In FinTech or authentication systems, that burst is more than enough to overwhelm payment gateways or run a successful credential-stuffing attack. The Algorithmic Fix: Sliding Window Counter To stop boundary spikes, we need a continuously sliding window rather than a rigid clock reset. Attempt 1: The Sliding Window Log (High Memory) You store a timestamps array (a Deque) for every user request and drop timestamps older than 60 seconds. While accurate, storing every single request timestamp takes $O(N)$ space. If your API receives millions of requests, your server memory dies instantly. Attempt 2: Sliding Window Counter (Optimal O(1) Math) Instead of keeping thousands of timestamps, we track only two integers : the request count of the previous window and the count of the current window . When a request arrives, we calculate an estimated request count by weighting the previous window based on how much time has passed in the current window: Estimated Requests = Current Cou

2026-08-23 原文 →
AI 资讯

Next step to client-side storage

Next step to client-side storage In my past one blog, I wrote about how I improve the performance of the application using the local storage. And the problem local storage solves. But now I face another problem about the client storage. My project is simply about order management software for the rental clothing industry. In the rental clothing industry, Showrooms or small shops have a big problem. The problem starts when one order has a single or multiple items that are booked in a particular time range. Now, a second order wants the same item in between that particular time range. If, by mistake, the second order books that item, then the problem starts. The item is booked two times in that particular time range. That is called double booking of the item. This mistake is created by the use of traditional register booking. Now, when I need to store the items data, that is a small amount of data, so I simply use the local storage. But now I need another and a big storage for storing order details. I build two features: first one is for showing all the orders and second one is for showing the full order. To implement those features and to maintain the user experience, I decide to store a small amount of data about the order on the client side. First, I decide to store data in local storage. But to store data in the local storage is not a good option because the local storage is used for storing small details about the application, and storing order details in the local storage compromises the performance of the application. Now I want a new storage option for storing order details. And again I find out, and that is the IndexedDB. To integrate IndexedDB in my application, I want to learn about that storage. I search multiple videos about IndexedDB, but no one is teaching me properly. After finding hundreds of tutorials, I finally found one tutorial that is teaching properly how to integrate IndexedDB in the application. Now I want to share that learning with you. To i

2026-08-23 原文 →
AI 资讯

I built a JSON toolkit that never sends your data anywhere

Most "paste your JSON here" tools online send that JSON to a server to process it. For internal API responses, config files, or anything with real data in it, that's not something I wanted to do — so I built JSONLinter , a JSON toolkit where literally everything happens client-side. What it does It started as a validator/formatter, then grew into 42 tools across six categories: Validate & Format — validation with precise error locations, pretty print, minify, JSON repair (fixes trailing commas, single quotes, unquoted keys, truncated JSON, etc.) View & Query — tree view, JSONPath queries, structural diff (key order doesn't matter), full-text search Data Converters — CSV, Excel, YAML, XML, SQL, Markdown, both directions Code Generators — infers a type model from a JSON sample and generates TypeScript, Python, Java, C#, Go, Kotlin, Swift, Rust, or PHP Schema Tools — JSON Schema validation + generation Encoding Tools — Base64, escape/unescape, JWT decode There's also an optional AI assistant on the validator page — it's bring-your-own-key (OpenAI or Anthropic), and since there's no backend at all, the key and your JSON go straight from your browser to the provider. I never see either. How it's built Stack is React 19 + TypeScript + Vite, Tailwind v4 for styling, CodeMirror 6 for the editor. A few things I had to solve that were more interesting than expected: Prerendering without SSR. I didn't want to take on a Next.js-style server just to get real HTML for crawlers. Instead, the build runs a headless Chromium pass (Playwright) over every route after vite build and saves the fully-rendered output to dist/<route>/index.html . Crawlers get real content and correct per-page meta tags on first paint; once JS loads, React takes over exactly like a normal SPA. No server, no hydration mismatches to worry about. Structural JSON diff. A text diff on two JSON documents is mostly useless because key order doesn't matter semantically. The diff tool parses both sides and compares t

2026-08-23 原文 →