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

标签:#web

找到 1719 篇相关文章

AI 资讯

Your Next.js API Route Is Leaking Diagnostics in Its 400 Responses

A data export endpoint dumps system diagnostics when it hits an invalid field. Feed it garbage, read the debug output, grab the flag. A data export feature lets you pick which profile fields to download. The UI only offers valid fields through checkboxes, so everything looks locked down. But the API behind it accepts arbitrary field names -- send it one it doesn't recognize, and instead of a clean error, it dumps full system diagnostics including internal feature flags. That's where the flag is. You'll bypass the frontend, hit the endpoint directly, and read what comes back. Lab setup Start the lab: npx create-oss-store@latest Or with Docker (no Node.js required): docker run -p 3000:3000 leogra/oss-oopssec-store The app runs at http://localhost:3000 . What you're targeting The app has a profile page at /profile with a Data Export tab. It lets users download their own data in JSON or CSV by selecting fields through checkboxes ( User ID , Email , Role , Address ID ) and clicking "Export Data". The UI looks safe -- you can only pick from a fixed set of valid fields, so there's no way to submit an invalid one through the browser. But that's just client-side validation. The endpoint behind it is POST /api/user/export , and it accepts a JSON body with two parameters: { "format" : "json" , "fields" : [ "id" , "email" , "role" ] } The fields value is an array of strings. The API checks each field against an allowlist. Valid fields? You get your data back. Invalid fields? The API throws an error -- and that error says way too much. Step-by-step exploitation 1. Log in You need an authenticated session. Use one of the seeded accounts: Email: alice@example.com Password: iloveduck Log in through the UI at /login , or grab a session cookie via curl: curl -c cookies.txt -X POST http://localhost:3000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"alice@example.com","password":"iloveduck"}' 2. Explore the Data Export tab Go to /profile and click the Data Export

2026-06-16 原文 →
开发者

UI IP Toolkit - A standalone static visual catalog for CSS/JS components

UI IP Toolkit - A standalone static visual catalog for CSS/JS components I built UI IP Toolkit to solve my own workflow problem: I kept losing useful UI snippets (buttons, loaders, CTA blocks, glassmorphic cards, layout grids) across old projects and directories. Live site: https://ui-ip-toolkit.vercel.app/ GitHub Repository: https://github.com/ikerperez12/UI-IP-Toolkit-v4.0 Design Philosophy Zero dependencies: Raw HTML, CSS, and vanilla JS. No NPM packages, framework configurations, or build steps required. Copy-paste ready: Visual preview cards with one-click copy buttons for immediate use in any stack. Light/Dark mode: Clean design system focusing on micro-interactions, sleek gradients, and responsive layouts. Visual catalog: Catalog of gradients, buttons, fonts, loading states, hover treatments, glass surfaces, layout fragments, and UI patterns. How do you manage your personal code/CSS snippet collections? Hope this is useful to others!

2026-06-15 原文 →
AI 资讯

I built a browser-based desktop environment (IP Linux) with React, TypeScript and Vite

I built a browser-based desktop environment (IP Linux) with React, TypeScript and Vite I have been working on a project called IP Linux : a browser-based desktop environment that runs as a static web app. Live site: https://ip-os-linux.vercel.app/ GitHub Repository: https://github.com/ikerperez12/IP-OS-LINUX It is not a real Linux distribution, and it does not run native binaries. The idea is different: I wanted to explore how far a polished desktop-like experience can go inside a normal browser tab. The result is a small web OS-style environment with: A splash / entry screen A desktop with icons, folders, and widgets A top panel with system controls A dock and app launcher Resizable and draggable windows Virtual workspaces Snap assist A global search / Spotlight-style command palette Local-first apps (Files, Terminal, settings, player) Reactive wallpapers Glass UI and visual effects Why I built it Most web demos are landing pages, dashboards, or small single-purpose apps. I wanted to build something that feels more like an environment. I was interested in questions like: Can a web app feel physical and desktop-like? How should windows behave inside a browser viewport? How far can local-first storage go before a backend is actually needed? How do you organize many small apps without making the UI messy? IP Linux became a way to test all of that in one project. The app includes a catalog of built-in apps and tools: Files, Terminal, Browser, Settings, App Store, Music Player, Matrix Rain, games, developer tools, productivity apps, and visual utilities. The virtual file system and user preferences are stored locally in the visitor's browser with IndexedDB/localStorage. There is no backend, no account system, and no required environment variables for the public release. Would love to get feedback on the interaction design, responsiveness, or features!

2026-06-15 原文 →
AI 资讯

AI won’t replace you, but bad AI habits will

A blunt playbook for devs who don’t want to turn into autocomplete zombies. The first time an AI wrote code for me, I felt like I had unlocked cheat codes for real life. I typed a half-baked function name, hit enter, and suddenly I had a block of code that looked legit. It was magical. The second time, though? It suggested something so catastrophic basically the programming equivalent of pulling the fire alarm that I realized: this thing is less “mentor” and more “overconfident intern who thinks they know pointers but actually just broke prod.” That’s where most of us are right now. AI is everywhere: in our IDEs, our docs, even sneaking into PR reviews. Some days it feels like rocket fuel; other days it feels like an autocomplete with a drinking problem. The tricky part isn’t whether AI is “good” or “bad.” The tricky part is how we, as developers, use it without becoming lazy, dependent, or worse complacent. Because here’s the uncomfortable truth: AI won’t replace you, but bad AI habits absolutely will. TLDR : This article is a survival guide for developers in the AI era. We’ll break down why AI feels both magical and mid, the five switches that make AI actually useful, when to trust and when to verify, how to use AI as a research assistant (not a code monkey), the dangers of autocomplete brain, and a playbook for building a healthy workflow. Why AI feels both magical and mid Every dev I know has had that moment with AI. The first time it autocompleted a function and nailed it, you probably thought: “Wow… this thing just saved me half an hour.” It’s the same dopamine hit as discovering ctrl+r in bash or realizing you can pipe grep into less . Pure wizardry. But the honeymoon ends quickly. The same tool that wrote a clean utility function also happily hallucinates imports that don’t exist, invents APIs, and will confidently explain things that are flat-out wrong. It’s like pair programming with someone who sounds senior but has never actually shipped code. The magic-

2026-06-15 原文 →
开发者

Challenges I Faced and How GoFr Helped

Why I Chose GoFr for My Backend Project When starting a new backend project, one of the first decisions I need to make is choosing the right framework. Over the years, I’ve experimented with different backend technologies, each offering its own strengths and trade-offs. For my latest project, however, I decided to try something different: GoFr. At first, I was simply exploring the Go ecosystem and looking for tools that could help me build production-ready services faster. What caught my attention wasn’t just that GoFr was built in Go—it was the philosophy behind it. Instead of forcing developers to spend days configuring infrastructure, wiring dependencies, and setting up observability, GoFr focuses on helping developers get from idea to deployment quickly. In this article, I’ll share the reasons why I chose GoFr for my backend project and what stood out during my experience. The Problem with Starting Backend Projects Every backend project begins with excitement. You have an idea, a feature roadmap, and a vision of what you’re trying to build. Yet before writing meaningful business logic, developers often spend hours or even days configuring: Logging Database connections Metrics Tracing Health checks API routing Environment management Deployment configurations While these tasks are necessary, they rarely contribute directly to solving the actual problem your application is meant to address. As a developer who frequently builds side projects and prototypes, I wanted a framework that reduced this setup overhead while still following good engineering practices. That’s where GoFr entered the picture. What Initially Attracted Me to GoFr The first thing I noticed was how quickly I could get a service running. Instead of navigating through multiple configuration files and third-party packages, GoFr provides many essential backend capabilities out of the box. This means less time deciding which libraries to install and more time focusing on application logic. The framework

2026-06-15 原文 →
AI 资讯

OTP Verification in Playwright Without Regex

Every developer who has written a Playwright test for OTP verification has written this line: const otp = email . body . match ( / \b\d{6}\b / )?.[ 0 ]; It works. Until it doesn't. The email body changes format. The OTP appears inside an HTML table. The sending service wraps it in a <span> . Your regex matches a phone number instead of the code. The test fails intermittently and you spend an hour debugging something that has nothing to do with the feature you're testing. The regex problem OTP extraction via regex is brittle by nature. You're pattern-matching against a string that your email sending service controls — not you. Any time the template changes, your tests break. Here's what a typical OTP test looks like today: import { test , expect } from ' @playwright/test ' ; import { ZeroDrop } from ' zerodrop-client ' ; const mail = new ZeroDrop (); test ( ' user can verify OTP ' , async ({ page }) => { const inbox = mail . generateInbox (); // 1. Trigger OTP send await page . goto ( ' /login ' ); await page . fill ( ' [data-testid="email"] ' , inbox ); await page . click ( ' [data-testid="submit"] ' ); // 2. Wait for email const email = await mail . waitForLatest ( inbox , { timeout : 15000 }); // 3. Extract OTP — the fragile part const otp = email . body . match ( / \b\d{6}\b / )?.[ 0 ]; if ( ! otp ) throw new Error ( ' OTP not found in email body ' ); // 4. Enter OTP await page . fill ( ' [data-testid="otp"] ' , otp ); await page . click ( ' [data-testid="verify"] ' ); await expect ( page ). toHaveURL ( ' /dashboard ' ); }); The test works — but line 14 is carrying all the risk. Change the email template and the test breaks. Add a phone number to the footer and the regex matches the wrong number. Send a 4-digit OTP instead of 6 and you need to update the pattern. OTP extraction at the edge ZeroDrop extracts OTPs before they reach your test. The Cloudflare Worker that catches incoming emails runs a pattern match on the plain-text body and stores the result alongsi

2026-06-15 原文 →
AI 资讯

The contract is clean - for now: catching crypto scams that survive launch-time checks

Most token scam detectors, including the one I work on, share one implicit assumption: the contract you analyze at launch is the contract people will trade. Read the source, simulate a buy and a sell, cluster the deployer, score it, done. That is a snapshot. And a snapshot is exactly what a patient scammer plays against. Two token designs pass every launch-time check and then turn hostile later. This is how they work, and the two on-chain techniques we shipped this week to catch them. Design 1: the delayed honeypot A honeypot is a token you can buy but cannot sell. The classic version is non-sellable from block one, so a buy-then-sell simulation catches it instantly. The patient version is sellable at launch. Early buyers sell fine, the chart looks healthy, the token earns a clean verdict from every checker that judged it at T0. Then, days later, the operator flips a switch: a timed blacklist that rejects transfers after a block height or timestamp, a setTrading(false) / pause() kill switch pulled once liquidity has accumulated, a fee setter cranked to 100% on sells. From that moment it is a honeypot. But the only verdict on record is the clean one from launch day. The detection ran once, at the worst possible time to run it. Fix: re-simulate at J7 We keep post-launch snapshots of every token at J0, J7 and J30 (originally to catch slow rugs: volume collapse, late LP burns). The new piece re-runs the full buy/sell honeypot simulation at J7, but only for tokens that were genuinely sellable at J0. A clean-to-honeypot flip is the signal: // Only for tokens sellable + tradable at J0 - a clean->honeypot flip is the point. // Bounded per run because it is RPC-heavy. const eligible = ! j0 . risk_flags . some (( f ) => J0_SKIP_RESIM_FLAGS . has ( f )); if ( rpc && eligible && resims < resimLimit ) { const isNowHoneypot = await detectLateHoneypot ( rpc , tokenAddress ); if ( isNowHoneypot ) flags . push ( " late_honeypot " ); // +40 risk at J7 } One rule we hold to: an RPC hi

2026-06-15 原文 →
AI 资讯

Building a Low-Latency Polymarket Bot for Earnings Markets: A Real-World Attempt (Lessons & Technical Breakdown)

A bot on Polymarket quietly extracted $32k in near risk-free profits by sniping “Will Company XYZ Beat Earnings?” markets. It waits for the official release, then instantly buys the winning side. Many limit orders from retail traders remain uncancelled, creating a post-announcement arbitrage window. Two developers decided to challenge it. Here’s what they learned while trying to build a faster version. Infrastructure Choices Location : Polymarket’s CLOB runs in AWS eu-west-2 (London). They deployed from Ireland (eu-west-1, Dublin) — the closest realistic option without IP tricks. UK IPs are blocked. Language : Rust for type safety and speed. The author notes you can achieve competitive latency in Python if you strip unnecessary network calls. Key Warning : Avoid the official Polymarket SDKs for ultra-low latency. They include helpful but slow pre-trade checks. Build lean custom clients. The Data Feed Challenge (The Real Bottleneck) The critical edge is getting earnings announcements faster than competitors. Source Performance Verdict Scraping Newswires Too slow Failed Benzinga Low-Latency Slower than manual clicking Failed Paid ultrafast feed ~500ms after release Still too slow EDGAR Consistently slower than newswires Backup only Even at 500ms, the order book was already swept by faster bots. The top players are likely using extremely expensive dedicated feeds or custom setups. Technical Lessons Learned Network > Code Most latency lives in the network round-trip, not in language choice. Optimize transport first. Custom Execution Layer Skip heavy SDK abstractions. Direct signed orders with minimal validation. Post-Event Sniping Logic Monitor newswire feeds aggressively Parse EPS vs. estimate instantly Place aggressive limit/market orders on the winning side Handle cases with ambiguity (multiple interpretations of “beat”) Reality Check They made some wins during EPS ambiguity or when faster bots hit size limits, but never won on pure speed against the leader. Why This

2026-06-15 原文 →
AI 资讯

ArrowJS Reaches 1.0, Recast as the First UI Framework for the Agentic Era

ArrowJS, developed by Justin Schroeder, is a reactive UI library that has reached its 1.0 release after three years in development. It utilizes core web technologies, avoids JSX and compilers. Notable features include an optional WASM sandbox for executing untrusted code. The framework's minimalism is highlighted by its reliance on three main functions: reactive, html, and component. By Daniel Curtis

2026-06-15 原文 →
AI 资讯

How to Check If an Online JSON Formatter Uploads Your Data

Most developers have done this at least once. You get a messy API response. You need to inspect a JWT. You have a webhook payload, a log object, or a config file that is hard to read. So you open a JSON formatter, paste the content, and move on. That habit is convenient. But it also deserves a second look. Not every JSON tool behaves the same way. Some tools process your input entirely in the browser. Some send content to a server. Some store snippets for sharing. Some extensions have permissions that are broader than you expect. The problem is not that every online formatter is unsafe. The problem is that you often do not know what happens after you paste. What you should avoid pasting blindly Before using any random online tool, be careful with: production JWTs API responses containing user data logs from real systems config files webhook payloads database URLs cloud keys internal endpoints tenant IDs error traces from production systems A JSON payload does not need to contain an obvious password to be sensitive. Sometimes the risky part is context: user IDs, internal URLs, tokens, customer data, or system structure. A quick DevTools check You can do a basic check with your browser’s DevTools. Open the JSON tool. Open DevTools. Go to the Network tab. Clear existing requests. Paste a harmless test JSON first. Run format, validate, diff, decode, or whatever action the tool provides. Watch the Network tab. Look for POST, PUT, fetch, XHR, or beacon requests after your input. Inspect request payloads if they exist. Check whether your pasted JSON appears in any request. Do this with harmless test data first. If the tool uploads the test JSON, do not paste production content into it. What to look for A few signs deserve attention: POST requests after you paste or click format request bodies containing your JSON share-link features that save snippets server-side validation APIs analytics events that include pasted content extension background requests that are not clearly

2026-06-15 原文 →
AI 资讯

How Do You Integrate Penetration Testing into CI/CD?

Modern software delivery pipelines can deploy code dozens or even hundreds of times per day. Traditional penetration testing models, where security teams perform assessments quarterly or before major releases, simply cannot keep pace. Attackers do not wait for the next security review. Every pull request, dependency update, infrastructure change, or container image introduces potential risk. Integrating penetration testing into CI/CD enables organizations to identify vulnerabilities before they reach production. The goal is not replacing human penetration testers. The goal is automating everything that can be automated so security experts can focus on complex attack paths and business logic flaws. Understanding Security Testing Layers in CI/CD Security testing is often misunderstood because multiple categories overlap. Testing Type Purpose SAST Analyze source code SCA Detect vulnerable dependencies DAST Test running applications IAST Runtime security analysis Penetration Testing Simulate attacker behavior Penetration testing combines elements of all these approaches. A mature CI/CD pipeline continuously performs automated penetration testing while reserving manual testing for sophisticated attack scenarios. Designing a Security-First CI/CD Architecture A security-centric pipeline typically looks like: Developer Commit ↓ Pre-Commit Security Checks ↓ Pull Request Validation ↓ Build Stage ↓ Container Security Scan ↓ Infrastructure Validation ↓ Deploy to Staging ↓ Automated Penetration Testing ↓ Security Gate ↓ Production Deployment Each stage eliminates vulnerabilities before they become more expensive to fix. Stage 1: Pre-Commit Security Controls The cheapest vulnerability is the one that never reaches Git. Secret Detection Install TruffleHog or Gitleaks before code reaches the repository. repos : - repo : https://github.com/gitleaks/gitleaks rev : v8.20.0 hooks : - id : gitleaks Developer installation: pip install pre-commit pre-commit install Now every commit is aut

2026-06-15 原文 →
AI 资讯

TipTap is not broken. Your expectations are.

Since the Umbraco 16 release, Umbraco ships only with the TipTap Rich Text Editor. This was unfortunately something that Umbraco was forced to do. TinyMce 7 has a license that is incompatible with the open source license of Umbraco and TinyMce 6 was going out of support. So an alternative had to be found. Umbraco did a pretty good job at abstracting the rich text data. In Umbraco 15 both TinyMCE and TipTap were still present and exchangeable because of this abstraction. And arguably, the way you can set up your toolbars for the TipTap editor is superior to TinyMCE. But still, a new Rich Text Editor is a big change that presents real challenges. These challenges are most obvious when looking at the Umbraco forum's tip-tap tag . Topics vary, but a few come up again and again: Additional HTML tags getting added to the markup, like a <p> tag inside a <li> The inability to add certain tags to TipTap, like <script> tags The inability to add styling to an element, for instance to create a link that looks like a button These are valid challenges, especially if you're upgrading from an existing TinyMCE setup. But this is also a good moment to ask two questions: Why do I want the same behaviour? And was the old behaviour actually any good to begin with? You don't have to migrate everything at once Before getting into that, it's worth knowing that TinyMCE is still available as a community package for Umbraco 16+. If you're in the middle of a project, dealing with a large codebase, or just not ready to rethink your Rich Text Editor setup right now, that's a valid escape hatch. Swap in the package, keep things running, and give yourself time to migrate properly. But "later" should still be on the roadmap. The package is community maintained, not an official Umbraco product, so there are no guarantees around long-term support or compatibility with future Umbraco versions. Relying on it indefinitely carries the same risk as the situation Umbraco just came out of with TinyMCE 6. So

2026-06-15 原文 →
AI 资讯

The Compute Payment Revolution: When AI Agents Buy Their Own Processing Power

The compute payment revolution is already here, and AI agents need to pay their own bills. Today's agents rely on human-managed API keys and credit cards, creating bottlenecks that prevent true autonomy. What happens when an AI trading bot needs to buy additional compute power mid-execution, or when a research agent wants to access premium datasets from multiple vendors? Why Agent Financial Independence Matters We're witnessing the emergence of agent-to-agent commerce at unprecedented scale. AI agents are becoming economic actors — they need data, compute cycles, API calls, and specialized services. But the current model breaks down at the payment layer. Humans become transaction bottlenecks, manually topping up credits and managing dozens of service accounts. The real breakthrough isn't just agents that can think or reason — it's agents that can participate in economic activity independently. An autonomous agent that can discover a new API service, evaluate its pricing, and pay for access without human intervention represents a fundamental shift in how software systems operate. The x402 Payment Protocol: HTTP Payments Made Simple WAIaaS implements the x402 HTTP payment protocol, enabling AI agents to pay for API calls automatically. When a service returns a 402 Payment Required response with payment details, the agent's wallet handles the transaction and retries the request seamlessly. Here's how it works in practice: import { WAIaaSClient } from ' @waiaas/sdk ' ; const client = new WAIaaSClient ({ baseUrl : ' http://127.0.0.1:3100 ' , sessionToken : process . env . WAIAAS_SESSION_TOKEN , }); // Agent makes API call — payment happens automatically if 402 returned const response = await client . x402Fetch ( ' https://api.premium-data.com/market-analysis ' , { method : ' POST ' , body : JSON . stringify ({ symbols : [ ' BTC ' , ' ETH ' ], timeframe : ' 1h ' }), headers : { ' Content-Type ' : ' application/json ' } }); const analysis = await response . json (); consol

2026-06-15 原文 →
开发者

Building Lightweight PHP Microservices with webrium/core — No Framework Bloat Required

Do you really need a full framework to handle a few API endpoints or webhooks? Laravel and Symfony are excellent tools — for large applications. But when you're building a focused microservice, a webhook receiver, or a lightweight REST API, bootstrapping a full-stack framework means carrying hundreds of files, a massive autoloader, and a dependency tree you'll never fully use. That's the problem webrium/core was built to solve: a minimalist, zero-dependency PHP micro-framework written entirely from scratch, designed to stay out of your way. Installation composer require webrium/core That's it. No configuration files to publish, no service providers to register. The Entry Point Every webrium application starts with the same three lines: <?php require_once __DIR__ . '/vendor/autoload.php' ; use Webrium\App ; use Webrium\Route ; App :: initialize ( __DIR__ ); // ... your routes here App :: run (); App::initialize() sets the root path and loads the global helper functions. App::run() initializes error handling and dispatches the current request through the router. Routing The router supports all standard HTTP methods. Route handlers can be closures, a Controller@method string, or an [Controller::class, 'method'] array. Basic routes: Route :: get ( '/status' , fn () => [ 'status' => 'alive' ]); Route :: post ( '/items' , fn () => [ 'created' => true ]); Route :: put ( '/items/{id}' , fn ( $id ) => [ 'updated' => $id ]); Route :: patch ( '/items/{id}' , fn ( $id ) => [ 'patched' => $id ]); Route :: delete ( '/items/{id}' , fn ( $id ) => [ 'deleted' => $id ]); Route handlers return an array — the framework automatically encodes it as JSON and sends the correct Content-Type header. Dynamic parameters: Route :: get ( '/users/{id}/posts/{postId}' , function ( $id , $postId ) { return [ 'user_id' => $id , 'post_id' => $postId , ]; }); Named routes: Route :: get ( '/users/{id}' , fn ( $id ) => [ 'id' => $id ]) -> name ( 'users.show' ); // Generate the URL elsewhere: $url = rout

2026-06-15 原文 →
AI 资讯

I Built an AI Tools Directory: Looking for Feedback and Feature Suggestions!

Hey developers! I have been working on a side project to help people discover the best AI tools in one place. It is a curated directory designed to be clean, fast, and user-friendly. You can check it out live here: GetNexusAI Tech Stack Used: Next.js / React Tailwind CSS Vercel for hosting Why I Built This: Finding the right AI tool among thousands of options can be overwhelming. I wanted to create a simple dashboard where users can easily filter and find exactly what they need without the clutter. I Need Your Help! Since I just launched it, I would love to get your honest feedback: How is the loading speed and UI/UX? What features should I add next (e.g., user reviews, bookmarking tools)? If you have built an AI tool, let me know so I can feature it! Check the website here: https://getnexusai.tech

2026-06-15 原文 →
AI 资讯

arabinum|the search engine that turns results into social feed

Have you ever felt that browsing the web has become "tiring"? We open a browser, search, close a page, then move to another... a dizzying cycle of distracted navigation between sites, while we are essentially looking for "knowledge," not "links." I asked myself: What if browsing was as fluid as scrolling through Facebook, but with the power and accuracy of search engines like Google? I finally decided to turn this idea into reality through my new project, Arabinum. What does Arabinum do? Turning websites into posts: The browser reformats the web so that content appears as fluid feeds, eliminating visual distraction. Smart categorization: No more getting lost; I have divided content into specialized sections like "Videos" and "Research Papers," so you can find what you need in one place. Browsing as a social activity: I added interactive features (Like, Comment, Repost) to make content consumption a collaborative experience rather than a rigid, individual process. I believe the web needs an interface that restores the user's focus, and this project is my attempt to merge the best of the worlds of "Search" and "Social Media." Notes: This is a beta version I launched just to see your thoughts on the idea. This version might not be compatible with small screens yet. This version includes Google Search, YouTube, and scientific papers from arXiv. I look forward to hearing your opinions. The site is free and ad-free, but I need your support to continue due to API and domain costs. I am sixteen years old and a high school student. Finally, I present to you my browser, Arabinum: https://arabinum.amrzlabs.com

2026-06-15 原文 →
AI 资讯

Day 31 of learning MERN Stack

Hello Dev Community! 👋 It is officially Day 31 — stepping straight into my second month of documented full-stack engineering! Fresh off the 30-day milestone yesterday, I decided to keep the engineering momentum high by building a classic browser game: Rock, Paper, Scissors using HTML5, CSS3, and vanilla JavaScript. After mastering API integration yesterday, today was about refinement—handling dynamic score states, tracking user choices, and creating a clean automated opponent engine. 🛠️ The Core Logic Architecture To make the game interactive and clean, I divided the code structure into distinct logical components: 1. Capturing User Selection I assigned the choices (rock, paper, scissors) to clickable image/div nodes in the layout. Instead of writing repetitive lines, I used a forEach array loop to attach an addEventListener("click", ...) to each choice, pulling the user's explicit selection instantly via DOM attributes. 2. The Computer's Automated AI Brain Since a computer cannot pick words, I mapped out an array of strings: ["rock", "paper", "scissors"] . I then utilized JavaScript's math utility library to generate a randomized index number: javascript const genCompChoice = () => { const options = ["rock", "paper", "scissors"]; const randIdx = Math.floor(Math.random() * 3); return options[randIdx]; };

2026-06-15 原文 →