StyloBot-julkaisusarja: Behaviour-Aware TypeScript UI (Suomi (Finnish))

StyloBot-julkaisusarja: Behaviour-Aware TypeScript UI

Monday, 01 June 2026

//

17 minute read

Botin havaitseminen ei saa lopettaa sallimalla/block. Tämä raportti osoittaa, miten StyloBotin luokittelutulosta tulee TypeScriptin soveltamisloogikaaM SK3 Express- ja Fastify-server middlewareMSC4 handlebars-temppujen avustajatMST5 Nunjucks, ja EJSMSP7 sekä browser-verkkokomponentitMSL8 niin että UI:llänne voidaan muokata kokemusta sen sijaan, että se jarruttaisi sitä jälkikäteen.*

StyloBot

Euroopan unionin @stylobot/core ja @stylobot/node npm-paketit julkaistaan pian. jäljempänä esitetyt osiot kuvailevat pinta-alaa, jota ne esittävät.

StyloBot -sarja

  1. Käytänne, Ei identiteettiä: miksi StyloBot mallistaa asiakkaita käytännöllisesti
  2. Behaviour-Aware ASP.NET UI: serveri-renderoitu pinta .NET- sovelluksille
  3. Pitkällä aikavälillä tapahtuvan -käynnissä olevan .NET-palvelujen rajaton kasvun löytäminen ja korjaaminen:, luotettavuuden kurinalaisuus, joka pitää moottorin tuskallisena tuotannossa
  4. Behaviour-Aware TypeScript UI: tämä artikkeli
  5. Sidecar-arkkitehtuuri: miten havaitsemismoottori liitetään muihin kuin -.NET-palkkiin
  6. Oppiminen nopeuttamaan: mukautuva oppimisjärjestelmä, , neljä,- tasotasoinen muisti ja , tuomiovarasto
  7. Todistuksen testaaminen, joka ei jää rauhaan: tarkastusta koskevat säännökset : yksi BDF-tietokanta hallinnoi regressiaa M SK2 lastausta, , ja kalibrointia
  8. StyloExtract - paikallisen oppimisen HTML:n Markdown-muuttaja: HTMLM SK1Markdown-laaja, joka on päällekkäinen tunnistajan kanssa , walkinger bug lucidVIEW caught, ja dogfood loop, joka teki siitä rehellisen

StyloBotin havaitsemismoottori on kirjoitettu ASP:ssa, ., NET Core ja :, korkean suorituskyvyn kehys, jossa on erinomainen asynkki primitivi. Oppiminen nopeuttamaan: kun sormenjälki on nähty riittävän luottamuksellisestiM SK1 tuomiovaraus välttää koko detektaattorin kaasuputken ja vastaa mikrosekkunnissa

Esitys

Suurin osa TypeScriptin ekosysteemissä käytettävistä bot-tutkimuksista antaa teille yhden kahdesta asiasta: : -lähettilään sormenjäljen, joka kertoo, onko yhteyshenkilö näyttää automaattiselta, tai käyttäjän reeksiltä-Agent string, joka kiinnittää vain itsensä ilmoittavia bottejaM SK2

Niistä kumpikaan ei ole käyttökelpoista soveltamislaajassa.

Botd runs in the browser and has no view of request headers, TLS fingerprints , session behaviourM SK2 or IP reputation. A headless Chromium and a Googlebot look identical to itMST4 Pure UA matching packages MSC5is-bot, isbot) pyydä vain sitä, mikä haluaa tulla pyydettyäM SK1 Verkojärjestelmä-laajatuotteet (Cloudflare Bot ManagementMSC4 DataDome*) estää pyynnön etäisyydessä mutta ei voi mukauttaa sitä soveltamisalaanMST6 Kerro pyynnöstänne, että se on suljettu–, ette ole koskaan todennut, että pyyntöllä, joka on saavuttanut sovelluksenne, olisi ollut bot-mahdollisuus ja keskinkertainen riskivyöhyke–MST9 joten tilaussivullanne olisi voitu osoittaa törmäysvaihetta ja analyysit olisivat voineet sulkea sen pois –MST10 kaikki virhekoodista riippumatta

What StyloBot gives your TypeScript application is a verdict: typed result with a continuous bot probability scoreAiBot, Scraper, GoodBot, MaliciousBot,...), Riskiryhmä, Suositettu toiminta, ja uhkaluokitus. Teidän tehtävänne tämän tuomion kanssa riippuu teistä.

Tässä artiklassa tarkastellaan esikuvaa kaupungista ja esitetään, miten tuomiosta tulee käytännöllinen käytäntö jokaisella tasolla.

Tuomio

Ennen kaikkea, tämä on se, mikä saapuu

// @stylobot/core
interface Verdict {
  isBot: boolean;
  botProbability: number;        // 0.0–1.0 - not binary, a continuous score
  confidence: number;            // certainty in that score
  botType: BotType | null;       // 'AiBot' | 'Scraper' | 'GoodBot' | 'MaliciousBot' | ...
  botName: string | null;        // 'GPTBot', 'Googlebot', 'curl/8.9.1', ...
  riskBand: RiskBand;            // 'VeryLow' | 'Low' | 'Elevated' | 'Medium' | 'High' | 'VeryHigh'
  recommendedAction: RecommendedAction;  // 'Allow' | 'Throttle' | 'Challenge' | 'Block'
  threatScore: number;           // elevated when CVE probes or credential stuffing detected
  threatBand: ThreatBand;        // 'None' | 'Low' | 'Elevated' | 'High' | 'Critical'
}

Tarkastuspiste voi polkea Medium risk instead of blocking it. API voi sulkea AiBot liikkeeseenlasketut kiintiöt lukuun ottamatta todellisia käyttäjiä Elevated riskiä ilman, että puututaan kokemuksiin Low riskivierailijat. Mikään näistä ei ole mahdollista, jos havaitsemisen tulos on boolean verkkotasolla

Riskivyöhykkeet järjestyksessä: VeryLow, Low, Elevated, Medium, High, VeryHigh, Verified.

Asetus

npm install @stylobot/core @stylobot/node

# only needed for grpc mode
npm install @grpc/grpc-js @grpc/proto-loader

@stylobot/core runningtime-riippuvuus on nolla. Se sisältää tyyppimäärittelyt , REST-clienti, header parserM SK3 ja MSC4vaihtoehtoisestiMST5 gRPC-clientinMSV6 Se toimii nodessaMSL7 Denossa MSL8 ja Bunissa ilman muutoksiaMSR9

@stylobot/node provides Express middleware, a Fastify plugin, template helper utilities , and the verdict injectorM SK3 se riippuu @stylobot/core eikä mitään muuta runtimessa.

Serverin pinta

Miten tuomio saavuttaa välineet

Keskiteollisuudella on kolme menetelmää. Kaikki kolme tuottavat samaa req.stylobot muoto. Mitkä olette käyttämässä riippuu siitä, missä infrastruktuurin havaitsemisessa toimitaan

graph LR
    classDef input fill:none,stroke:#3b82f6,stroke-width:2px
    classDef good fill:none,stroke:#22c55e,stroke-width:2px
    classDef async fill:none,stroke:#a855f7,stroke-width:2px

    subgraph H ["headers mode - zero added latency"]
        GW[Gateway / Caddy / YARP]:::input -->|"X-StyloBot-* headers"| A[Express / Fastify]:::good
    end

    subgraph G ["grpc mode - HTTP/2, no JSON overhead"]
        B[Express / Fastify]:::good -->|"gRPC Detect RPC"| SC[StyloBot Sidecar :5090]:::async
    end

    subgraph R ["api mode - REST, full signal set"]
        C[Express / Fastify]:::good -->|"POST /api/v1/detect"| SC2[StyloBot Sidecar :5091]:::async
    end

headers menettely: havaitseminen suoritettiin etuvirtaan ottamalla vartiointiasemaan; välineet lukevat syötettyjä otsikoita ilman verkkovierailua . Tämä on tuotantomalli, kun Caddyn tai YARP:n ottama vartioitusasema on edessä

grpc menettely: välineet kutsuvat sivuautoa suoraan HTTP:n kautta @grpc/grpc-js. gRPC-yhteys ja sivuauton käyttöönotto yksityiskohdat ovat Luettelo sivuautoarkkitehtuurista.

api menettely:-puhelut POST /api/v1/detect yli HTTP/1.1. myös palaa reasons ( signals (muiden muodojen jättämä täydellinen taulukon tila

Keskinäinen ohjelmisto on aina epäonnistunut avata. Jos sivuautoa ei ole saavutettavissa tai se on ajautunut ulosM SK1 req.stylobot asetetaan sallivaan tyhjään tuomioon ja pyyntö jatkuu.

Siirretään se

Ekspresti

import express from 'express';
import { styloBotMiddleware } from '@stylobot/node';

const app = express();
app.use(styloBotMiddleware({ mode: 'headers' }));
// or:
app.use(styloBotMiddleware({ mode: 'grpc', endpoint: 'localhost:5090', timeout: 100 }));

Nopeuttaa:

import Fastify from 'fastify';
import { styloBotPlugin } from '@stylobot/node';

const fastify = Fastify();
await fastify.register(styloBotPlugin, { mode: 'headers' });

Lisätä tyyppijulistus, jos haluatte kirjatun pääsyn nopeuttamispyyntöihin:

// types.d.ts
import type { StyloBotResult } from '@stylobot/node';
declare module 'fastify' {
  interface FastifyRequest { stylobot: StyloBotResult; }
}

Kaupan etu

Samat näytteet varastolta ASP.NET artikla, tuotesivutM SK1 tilauscheckout, liittymä , lehtitiedoteMSC4 mutta TypeScript-muodossaMST5 havaitsemistulos on samaMSV6 mitä muuttuu on se, miten pinta paljastaa sen

Page 1: Tuotteen sivu

Hintojen hävittäjät alkavat täällä. He haluavat tuotenimiäM SK1 hintoja , ja varastojen tasoa. Te haluatte luettelon, jonka hakukoneet voivat indeksoida ja joka on hyödyllinen ihmisille välittämättä kaupallisia signaaleja järjestelmälliselle sadonkorjuukselleMSC4

Scenario: hintojen purkaminen koittuu /products/:id. Se ei näe mitään alennuskoodiaM SK1 ei lisätä -to-kart-puppua, eikä mitään ostosignaalia, jota olisi syytä käyttääMSC5

Tieliikenteen hallintajärjestelmä:

app.get('/products/:id', (req, res) => {
  const { verdict } = req.stylobot;
  const product = getProduct(req.params.id);

  res.render('product', {
    product,
    sbVerdict: verdict,
    showDiscount:   verdict.riskBand === 'VeryLow' || verdict.riskBand === 'Low',
    showBuyButton:  !verdict.isBot,
    showCartWarning: verdict.recommendedAction === 'Challenge',
    isSearchBot:    verdict.botType === 'SearchEngine' || verdict.botType === 'VerifiedBot',
  });
});

malli (Handlebars):

{{! verified crawlers get structured metadata instead of commercial UI }}
{{#if isSearchBot}}
  <meta name="description" content="{{product.name}} -{{product.category}}." />
  <p>{{product.description}}</p>
{{else}}

  {{! discount only for low-risk human visitors }}
  {{#if showDiscount}}
    <div class="alert alert-success">
      Member price: use code <strong>LOYAL10</strong> for 10% off.
    </div>
  {{/if}}

  {{! add-to-cart only for non-bot traffic }}
  {{#if showBuyButton}}
    <form method="post" action="/cart/add">
      <input type="hidden" name="productId" value="{{product.id}}" />
      {{#if showCartWarning}}
        <p class="text-warning">Additional verification may be required at checkout.</p>
      {{/if}}
      <button type="submit" class="btn btn-primary">Add to Cart</button>
    </form>
  {{else}}
    <p class="text-muted">Purchase available to human visitors.</p>
  {{/if}}

{{/if}}

Käytettävissä on kolme mallia. Crawlerin eriyttäminenM SK1 SearchEngine ja VerifiedBot saada rakenteellisia metatietoja ilman kaupallisia signaaleja, mikä on se, mitä he itse asiassa tarvitsevat Challenge on varoitus, ei ryhmää. epäilyttävät istunnot voivat edelleen ostaaM SK2

Page 2: Tarkastus

Petosten automatisointi, korttitesteritM SK1 voucher brute -forcers, ja kirjoitetut reterit kaikki lähentyvät tarkastuksen yhteydessäMSC4 Tavoitteena on puolustaa perusteellisesti ilman CAPTCHA-korttia

Scénario: osuuskorttiM SK1kokeet bot-iskut /checkout. Se näkee kuolleenM SK1 päättyvän viestin , toimittaa hunajapotin- täytetyn lomakkeenMSC4 ja saa hiljaisen vahvistuksen ilman toistamiseen tähtäävää kannustimia

flowchart TD
    classDef input fill:none,stroke:#3b82f6,stroke-width:2px
    classDef good fill:none,stroke:#22c55e,stroke-width:2px
    classDef problem fill:none,stroke:#ef4444,stroke-width:2px

    A([Visitor reaches /checkout]):::input --> B{bot?}
    B -->|yes| C[Dead-end message - no form]:::problem
    B -->|no| D{risk band}
    D -->|Low| E[Express checkout CTA]:::good
    D -->|Elevated| F[Standard checkout CTA]:::good
    D -->|High+| G[Phone number - no online path]:::problem
    E & F --> H[POST /checkout/order]
    H --> I{honeypot triggered?}
    I -->|yes| J[Silent fake confirmation]:::problem
    I -->|no| K[Process real order]:::good

Reitti:

app.get('/checkout', (req, res) => {
  const { verdict } = req.stylobot;
  res.render('checkout', {
    sbVerdict: verdict,
    showForm:     !verdict.isBot,
    showExpress:  verdict.riskBand === 'VeryLow' || verdict.riskBand === 'Low',
    showStandard: ['VeryLow','Low','Elevated'].includes(verdict.riskBand),
    showPhone:    ['High','VeryHigh'].includes(verdict.riskBand),
  });
});

app.post('/checkout/order', (req, res) => {
  // honeypot fields are invisible to humans; bots fill everything
  if (req.body.hp_name || req.body.hp_email) {
    return res.redirect('/checkout/confirmed');  // silent fake - no retry incentive
  }
  return processRealOrder(req, res);
});

malli:

{{#if showForm}}
  <form method="post" action="/checkout/order">

    {{! invisible honeypot trap - humans leave blank, bots fill everything }}
    <div style="position:absolute;left:-9999px;opacity:0" aria-hidden="true">
      <input type="text" name="hp_name" tabindex="-1" autocomplete="off" />
      <input type="email" name="hp_email" tabindex="-1" autocomplete="off" />
    </div>

    {{#if showExpress}}
      <button type="submit" name="express" value="true" class="btn btn-success btn-lg">
        Express Checkout
      </button>
    {{/if}}

    {{#if showStandard}}
      <button type="submit" class="btn btn-primary">Proceed to Payment</button>
    {{/if}}

    {{#if showPhone}}
      <p>Please call us to complete your order: <strong>0800 123 456</strong></p>
    {{/if}}

  </form>
{{else}}
  <p class="text-muted">Checkout is available to human visitors only.</p>
{{/if}}

Honeypotin poisheittäminen on avainasemassa tässä asiassa. virheen palaute opettaa hyökkääjiä toistamaan; hiljainen väärennetty vahvistus tuhlaa heidän ajansa , ja vahvistusta koskeva sivu näyttää samankaltaiselta, oliko tilaus todellinen vai poisheitettuM SK3 Express checkout trust-etuksi | ( ei ole standardi |) tarkoittaa, että vain tilaisuudet, jotka ovat saaneet sen, saavat lyhyemmän tien <div> wrapper osaksi yhteistä käsipide-aluetta ({{> honeypot}}) sen sijaan, että jokaisessa suojatussa muodossa toistetaan sisäinen malliblokti

Page 3: Login

Liittyminen on luottamuksellista-varustamisaluettaM SK1kauppaa koskevat sopimukset ovat erilaisia kuin lähtöä varten tehdyt sopimuksentekotoimet : virheellinen myönteinen sopimus saattaisi menettää myynnin; puuttunut luottamuslauseke-varmistamistoimissa hyökkäys menettää tilinpäätöksen. täytäntöönpano voi olla tiukempaa

Scenario: todistusaineistoM SK1kirjanpitäjät /login. Se näkee pelotteellisen viestin /login/denied ennen mahdollisten todentamistoimien toteuttamista.

app.get('/login', (req, res) => {
  const { verdict } = req.stylobot;
  res.render('login', {
    sbVerdict: verdict,
    showWarning: verdict.isBot,
    showRisk:    ['High','VeryHigh'].includes(verdict.riskBand),
  });
});

app.post('/login', async (req, res) => {
  if (req.body.hp_user || req.body.hp_pass) {
    return res.redirect('/login/denied');
  }
  if (req.stylobot.verdict.isBot) {
    return res.redirect('/login/denied');
  }
  return authenticate(req, res);
});
{{#if showRisk}}
  <div class="alert alert-danger">
    High-risk signals detected. Login attempts are logged.
  </div>
{{/if}}

{{#if showWarning}}
  <div class="alert alert-warning">
    Automated login attempts are detected and blocked.
  </div>
{{/if}}

<form method="post" action="/login">
  <div style="position:absolute;left:-9999px;opacity:0" aria-hidden="true">
    <input type="text" name="hp_user" tabindex="-1" autocomplete="off" />
    <input type="password" name="hp_pass" tabindex="-1" autocomplete="off" />
  </div>
  <div class="form-group">
    <label for="email">Email</label>
    <input type="email" id="email" name="email" autocomplete="email" />
  </div>
  <div class="form-group">
    <label for="password">Password</label>
    <input type="password" id="password" name="password" autocomplete="current-password" />
  </div>
  <button type="submit" class="btn btn-primary">Sign In</button>
</form>

Bot näkee pelotteen ennen kuin esittää. Jos se esittää joka tapauksessaMSC1 hunajapotti kiinnittää senM SK2 Jos hän jollakin tavalla välttää hunajanpottin, verdict.isBot on lopullinen serveri- sivutarkastelu ennen mahdollisen todentamislogiikan käyttöönottoa . Kolme kerrosta

Page 4: Newsletter

Älykkäitä crawlerejä on eri asia. Ne eivät pyri brutoimaan- pakottamaan tileitä tai korjaamaan hintojaM SK2 ne syövät sisältöä mallikoulutusta varten . Ne ovat usein rehellisiä identiteetin suhteenMSC4 mikä tarkoittaa, että oikea vastaus on kaupallinen eikä vastakkainasetteluinen

Scenario: GPTBot-iskut /newsletter. Tietojen lisensointia koskeva viesti nähdään tilaajahinnan sijasta

app.get('/newsletter', (req, res) => {
  const { verdict } = req.stylobot;
  res.render('newsletter', {
    sbVerdict:     verdict,
    isHuman:       !verdict.isBot,
    isAiBot:       verdict.botType === 'AiBot',
    isOtherBot:    verdict.isBot && verdict.botType !== 'AiBot',
  });
});

app.post('/newsletter/subscribe', (req, res) => {
  if (req.body.hp_email2 || req.stylobot.verdict.isBot) {
    return res.redirect('/newsletter/thanks');  // silent discard
  }
  mailingList.subscribe(req.body.email);
  return res.redirect('/newsletter/thanks');
});
{{#if isHuman}}
  <p>Get exclusive deals delivered to your inbox. Unsubscribe any time.</p>
{{/if}}

{{#if isAiBot}}
  <div class="alert alert-info">
    This subscription endpoint is for human readers.
    For data licensing enquiries, <a href="/contact">contact us directly</a>.
  </div>
{{/if}}

{{#if isOtherBot}}
  <div class="alert alert-warning">
    Automated subscription attempts are discarded.
  </div>
{{/if}}

<form method="post" action="/newsletter/subscribe">
  <div style="position:absolute;left:-9999px;opacity:0" aria-hidden="true">
    <input type="email" name="hp_email2" tabindex="-1" autocomplete="off" />
  </div>
  <div class="form-group">
    <input type="email" name="email" placeholder="[email protected]" autocomplete="email" />
  </div>
  <button type="submit" class="btn btn-success">Subscribe</button>
</form>

AiBot ei ole vain toinen vihamielinen merkintä, se on luokittelu, joka mahdollistaa liiketoiminnan vastauksen.Lisensointiviesti on hyödyllisempää kuin ‐403:, sillä siinä kerrotaan operaattorille, mistä he ovat tekemisissä ja annetaan heille mahdollisuus ryhtyä toimiin.

mallin avustajat

Tuomion sisällyttäminen malliin

sbVerdictInjector suoritetaan havaitsemisen jälkeen middleware ja panee tuomion res.locals:

import { sbVerdictInjector } from '@stylobot/node';

app.use(styloBotMiddleware({ mode: 'headers' }));
app.use(sbVerdictInjector({ mode: 'gateway' }));
// or for direct sidecar calls (REST port, not the gRPC port):
app.use(sbVerdictInjector({ mode: 'sidecar', endpoint: 'http://localhost:5091' }));

res.locals.sbVerdict on saatavilla jokaisessa mallissa. res.locals.sbVerdictScript on sisäinen <script> merkintä, joka asettaa window.__sb hakukonekomponenttien osalta.

Apuvälit

määritellä RISK_ORDER Nunjucksin ja EJS:n avustajat käyttävät samaa kartaa ):

import type { Verdict, RiskBand } from '@stylobot/core';

const RISK_ORDER: Record<string, number> = {
  Unknown: 0, VeryLow: 1, Low: 2, Elevated: 3, Medium: 4, High: 5, VeryHigh: 6, Verified: 7,
};

// register on your Handlebars engine instance
hbs.engine({
  helpers: {
    // {{#sbGate sbVerdict "Low"}}...{{else}}...{{/sbGate}}
    sbGate(verdict: Verdict | null, maxRisk: string, options: any) {
      if (!verdict) return options.fn(this);
      return RISK_ORDER[verdict.riskBand] <= RISK_ORDER[maxRisk]
        ? options.fn(this)
        : options.inverse(this);
    },

    // {{#sbIsBot sbVerdict}}...{{else}}...{{/sbIsBot}}
    sbIsBot(verdict: Verdict | null, options: any) {
      return verdict?.isBot ? options.fn(this) : options.inverse(this);
    },

    // {{#sbBotType sbVerdict "AiBot"}}...{{/sbBotType}}
    sbBotType(verdict: Verdict | null, type: string, options: any) {
      return verdict?.botType === type ? options.fn(this) : options.inverse(this);
    },

    // {{#sbMinRisk sbVerdict "High"}}...{{/sbMinRisk}}
    sbMinRisk(verdict: Verdict | null, minRisk: string, options: any) {
      if (!verdict) return options.inverse(this);
      return RISK_ORDER[verdict.riskBand] >= RISK_ORDER[minRisk]
        ? options.fn(this)
        : options.inverse(this);
    },
  },
});

Esimerkeissä:

{{#sbGate sbVerdict "Low"}}
  <a href="/checkout/express" class="btn btn-success">Express Checkout</a>
{{else}}
  <a href="/checkout" class="btn btn-secondary">Checkout</a>
{{/sbGate}}

{{#sbBotType sbVerdict "AiBot"}}
  <div class="alert alert-info">AI crawler detected. Data licensing info above.</div>
{{/sbBotType}}

{{#sbMinRisk sbVerdict "High"}}
  <div class="alert alert-danger">High-risk session. Some features restricted.</div>
{{/sbMinRisk}}

Nunjukkit

import nunjucks from 'nunjucks';

// RISK_ORDER - same map defined in the Handlebars section above

class SbGateExtension {
  tags = ['sbgate'];
  parse(parser: any, nodes: any, lexer: any) {
    const tok = parser.nextToken();
    const args = parser.parseSignature(null, true);
    parser.advanceAfterBlockEnd(tok.value);
    const body = parser.parseUntilBlocks('else', 'endsbgate');
    let elseBody = null;
    if (parser.skipSymbol('else')) {
      parser.skip(lexer.TOKEN_BLOCK_END);
      elseBody = parser.parseUntilBlocks('endsbgate');
    }
    parser.advanceAfterBlockEnd();
    return new nodes.CallExtension(this, 'run', args, [body, elseBody]);
  }
  run(context: any, maxRisk: string, body: any, elseBody: any) {
    const v = context.ctx.sbVerdict;
    const fits = !v || RISK_ORDER[v.riskBand] <= RISK_ORDER[maxRisk];
    return fits ? body() : (elseBody?.() ?? '');
  }
}
env.addExtension('SbGateExtension', new SbGateExtension());
{% sbgate "Low" %}
  <a href="/checkout/express">Express checkout</a>
{% else %}
  <a href="/checkout">Checkout</a>
{% endsbgate %}

EJS-järjestelmä

EJS:ssä ei ole lohkohelporeita,, mutta paikalliset toiminnot kattavat suurimman osan tapauksista puhtaastiM SK1

// RISK_ORDER - same map defined in the Handlebars section above

app.use((req, res, next) => {
  const v = res.locals.sbVerdict ?? null;
  res.locals.sbBelowRisk = (max: string) =>
    !v || RISK_ORDER[v.riskBand] <= RISK_ORDER[max];
  res.locals.sbAboveRisk = (min: string) =>
    v && RISK_ORDER[v.riskBand] >= RISK_ORDER[min];
  res.locals.sbIsBot  = () => v?.isBot ?? false;
  res.locals.sbBotIs  = (type: string) => v?.botType === type;
  next();
});
<% if (sbBelowRisk('Low')) { %>
  <a href="/checkout/express" class="btn btn-success">Express Checkout</a>
<% } else { %>
  <a href="/checkout" class="btn btn-secondary">Checkout</a>
<% } %>

<% if (sbBotIs('AiBot')) { %>
  <div class="alert alert-info">AI crawler. Data licensing enquiries via /contact.</div>
<% } %>

Lähtäjän pinta

Tuomioistuimen tuomion sisällyttäminen браузерiin

Lisäys {{{sbVerdictScript}}} layout-päällystönne. Se on

<script>window.__sb = {"isBot":false,"botProbability":0.12,"riskBand":"Low","recommendedAction":"Allow",...}</script>

Sitten laaditaan elementtipaketti:

<head>
  {{{sbVerdictScript}}}
  <script type="module" src="/js/sb-elements.js"></script>
</head>

<sb-gate>: näyttää tai peittää sisältöä riskivyöhykkeen mukaan

<!-- only shown when riskBand <= 'low' -->
<sb-gate max-risk="low">
  <a href="/checkout/express" class="btn btn-success">Express Checkout</a>
</sb-gate>

<!-- only shown when riskBand >= 'elevated' -->
<sb-gate min-risk="elevated">
  <div class="alert alert-warning">Unusual activity detected on your session.</div>
</sb-gate>

<sb-adapt>: valitse ensimmäinen sopiva tapaus

<sb-adapt>
  <sb-case max-risk="low">
    Standard checkout - enter your card details below.
  </sb-case>
  <sb-case max-risk="medium">
    Additional verification is required before we can process your order.
  </sb-case>
  <sb-case>
    Automated checkout access is not permitted.
  </sb-case>
</sb-adapt>

<sb-adapt> valitsee ensimmäisen <sb-case> jonka max-risk fits and hides the rest. Lopullinen <sb-case> ei max-risk -kaikki <sb-gate> ja <sb-adapt> kuunnelkaa sb:verdict event ja re-arvioida, muuttuuko tuomio ensimmäisen maalien jälkeen

<sb-widget>: palvelijaM SK1 luovutetut nesteydet

<sb-gate> hides content client-side. Jos tarvitsette robotin, joka saa erilaista markuptiaM SK2 ei peiteltyä markupia , tarvitsette fragmentin, jonka on esitettävä serverissä mallissa käytettävissä olevan havaitsemista koskevan kontekstin kanssa

<sb-widget> lukee nestemuodon mallia suoralta sivulta <template> element, liittää kaikki widget-pyynnöt sivuun yhdeksi kierrosta-tripM SK2 ja korvaa itsensä palautetulla HTML:lläMSC3

<sb-widget data-sb-widget="checkout-cta">
  <template>
    {% if recommendedAction == 'Block' %}
      <p class="text-danger">Automated checkout is blocked.</p>
    {% elsif botType == 'AiBot' %}
      <p>AI crawlers cannot complete purchases. <a href="/contact">Data licensing enquiries</a>.</p>
    {% elsif isBot %}
      <p class="text-muted">Checkout is available to human visitors.</p>
    {% else %}
      <a href="/checkout/express" class="btn btn-success">Express Checkout</a>
    {% endif %}
  </template>
</sb-widget>

Esimerkkivaihtoehtot: isBot, botProbability, confidence, botType, botName, riskBand, recommendedAction, threatScore, threatBand. Lisätään kaikki vars puhelua tehdessitte siirretään serverin-puolelle RenderWidget suoraan.

Kaikki <sb-widget> osatekijät, jotka liittyvät samaan mikrotaskin tikkiin, kootaan yhteen pyyntöön. Puolet, joissa on viisi widgetiä, muodostavat yhden rundan

sequenceDiagram
    participant B as Browser
    participant C as Coordinator
    participant S as /_stylobot/partials/render
    participant L as Fluid / Liquid

    B->>C: sb-widget#checkout-cta registers
    B->>C: sb-widget#promo-banner registers
    B->>C: sb-widget#nav-links registers
    Note over C: queueMicrotask - one batch
    C->>S: POST { widgets: { checkout-cta: "...", promo-banner: "...", nav-links: "..." } }
    S->>L: render each template with verdict context
    L-->>S: rendered HTML fragments
    S-->>C: <div data-sb-widget="checkout-cta">...</div> ...
    C-->>B: each sb-widget replaced in DOM

Lyhyesti sanottuna

Komponenti SSK1 Layer Mitä se tekee S
styloBotMiddleware Ekspresti Liitteet req.stylobot header-osoitteiden välityksellä / gRPC
styloBotPlugin Nopeuttaa Sama, kuin nopeuttaa plugin decorateRequest
sbVerdictInjector Express Väestö res.locals.sbVerdict ja sbVerdictScript
Apuvälineet toimenpidebareihin Server-templatet sbGate, sbIsBot, sbBotType, sbMinRisk auktorit
Nunjucks-laajentaminen Server-temppuja {% sbgate "Low" %}...{% endsbgate %}
EJS:n paikalliset mallit sbBelowRisk(), sbAboveRisk(), sbIsBot(), sbBotIs()
<sb-gate> Lähtölähettiläs sb:verdict
<sb-adapt> Lähtäjä Ottakaa ensimmäinen sopiva tapaus luettelosta.
<sb-widget> Browser Fetch server-rendered Liquid fragmentM SK3 batched per tick SSK4
StyloBotGrpcClient Node / Bun SSK2 Deno Suora gRPC-klientti muiden kuin

Seuraava versio sarjasta: Sidecar-arkkitehtuuri, millä tavoin havaitsemismoottori liitetään muihin kuin -.NET-palkkiin, , Go SDK:hen,, Caddy- pluginiin ja siihen liitettyyn gRPC-yhteyteen

Jos olette saapunut tänne .NET-puolelta Behaviour-Aware ASP.NET UI kattaa samat storefront-muutokset merkintähelpoitteilla ja toimintafiltreillä; moottoreiden luottamuksen parantaminen, joka säilyttää moottorin muistin stable under sustainable traffic is in Pitkällä aikavälillä tapahtuvan -käynnissä olevan .NET-palvelujen rajaton kasvun löytäminen ja korjaaminen. Elävä moottoriM SK1 Dashboard , ja kaupalliset valvontalaitteet stylobot.net.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.