Kurz: Vytvoření jednostránkové aplikace pomocí rozhraní API webové vyhledávání BinguTutorial: Create a single-page app using the Bing Web Search API

Na této jednostránkové aplikaci můžete vidět, jak načíst, analyzovat a zobrazit výsledky vyhledávání z rozhraní API Bingu pro vyhledávání na webu.This single-page app demonstrates how to retrieve, parse, and display search results from the Bing Web Search API. V tomto kurzu se používají standardní jazyk HTML a šablony stylů CSS a kurz se zaměřuje na kód jazyka JavaScript.The tutorial uses boilerplate HTML and CSS, and focuses on the JavaScript code. Jazyk HTML, šablony stylů CSS a soubory JS jsou k dispozici na GitHubu s pokyny pro rychlý start.HTML, CSS, and JS files are available on GitHub with quickstart instructions.

Tato ukázková aplikace může provádět následující akce:This sample app can:

  • Volání rozhraní API Bingu pro vyhledávání na webu s možnostmi pro hledáníCall the Bing Web Search API with search options
  • Zobrazení výsledků webu, obrázků, zpráv a videaDisplay web, image, news, and video results
  • Stránkování výsledkůPaginate results
  • Správa klíčů předplatnéhoManage subscription keys
  • Zpracování chybHandle errors

Abyste mohli použít tuto aplikaci, potřebujete účet služby Azure Cognitive Services s rozhraními API Bingu pro vyhledávání.To use this app, an Azure Cognitive Services account with Bing Search APIs is required. Pokud účet nemáte, můžete k získání klíče předplatného použít bezplatnou zkušební verzi.If you don't have an account, you can use the free trial to get a subscription key.

PožadavkyPrerequisites

Tady je pár věcí, které budete potřebovat ke spuštění aplikace:Here are a few things that you'll need to run the app:

  • Node.js 8 nebo novějšíNode.js 8 or later
  • Klíč předplatnéhoA subscription key

Získání zdrojového kódu a instalace závislostíGet the source code and install dependencies

Prvním krokem je naklonování úložiště se zdrojovým kódem ukázkové aplikace.The first step is to clone the repository with the sample app's source code.

git clone https://github.com/Azure-Samples/cognitive-services-REST-api-samples.git

Potom spusťte npm install.Then run npm install. Pro účely tohoto kurzu je jediná závislost Express.js.For this tutorial, Express.js is the only dependency.

cd <path-to-repo>/cognitive-services-REST-api-samples/Tutorials/Bing-Web-Search
npm install

Komponenty aplikaceApp components

Ukázková aplikace, kterou vytváříme, se skládá ze čtyř částí:The sample app we're building is made up of four parts:

  • bing-web-search.js – Naše aplikace Express.js.bing-web-search.js - Our Express.js app. Zpracovává logiku žádost/odpověď a směrování.It handles request/response logic and routing.
  • public/index.html – Kostra naší aplikace. Definuje, jak se budou zobrazovat data uživateli.public/index.html - The skeleton of our app; it defines how data is presented to the user.
  • public/css/styles.css – Definuje styly stránky, jako jsou například písma, barvy a velikost textu.public/css/styles.css - Defines page styles, such as fonts, colors, text size.
  • public/js/scripts.js – Obsahuje logiku provádění žádostí na rozhraní API Bingu pro vyhledávání na webu, správy klíčů předplatného, zpracování a analýzy odpovědí a zobrazení výsledků.public/js/scripts.js - Contains the logic to make requests to the Bing Web Search API, manage subscription keys, handle and parse responses, and display results.

Tento kurz se zaměřuje na scripts.js a logiku potřebnou k volání rozhraní API Bingu pro vyhledávání na webu a zpracování odpovědi.This tutorial focuses on scripts.js and the logic required to call the Bing Web Search API and handle the response.

Formulář HTMLHTML form

index.html obsahuje formulář, který umožňuje uživateli vyhledávat a vybírat možnosti hledání.The index.html includes a form that enables users to search and select search options. Když se formulář odešle, aktivuje se atribut onsubmit a zavolá metodu bingWebSearch() definovanou v scripts.js.The onsubmit attribute fires when the form is submitted, calling the bingWebSearch() method defined in scripts.js. Funkce má tři argumenty:It takes three arguments:

  • Vyhledávací dotazSearch query
  • Vybrané možnostiSelected options
  • Klíč předplatnéhoSubscription key
<form name="bing" onsubmit="return bingWebSearch(this.query.value,
    bingSearchOptions(this), getSubscriptionKey())">

Možnosti proxyQuery options

Formulář HTML obsahuje možnosti, které se mapují k parametrům dotazu v rozhraní API Bingu pro vyhledávání na webu verze 7.The HTML form includes options that map to query parameters in the Bing Web Search API v7. Tato tabulka obsahuje podrobný přehled, jak můžou uživatelé filtrovat výsledky hledání pomocí ukázkové aplikace:This table provides a breakdown of how users can filter search results using the sample app:

ParametrParameter PopisDescription
query Textové pole pro zadání řetězce dotazuA text field to enter a query string.
where Rozevírací nabídka pro výběr trhu (místo a jazyk)A drop-down menu to select the market (location and language).
what Zaškrtávací políčka pro upřednostnění konkrétních typů výsledků.Checkboxes to promote specific result types. Když například upřednostníte obrázky, zvýší se hodnocení obrázků ve výsledcích hledání.Promoting images, for example, increases the ranking of images in search results.
when Rozevírací nabídka, která umožní uživateli omezit výsledky vyhledávání na dnešek, tento týden nebo tento měsícA drop-down menu that allows the user to limit the search results to today, this week, or this month.
safe Zaškrtávací políčko pro povolení funkce Bezpečné hledání v Bingu, která filtruje obsah pro dospěléA checkbox to enable Bing SafeSearch, which filters out adult content.
count Skryté pole.Hidden field. Počet výsledků hledání, který se má vrátit u jednotlivých žádostí.The number of search results to return on each request. Pokud chcete zobrazit méně nebo více výsledků na stránku, můžete tuto hodnotu změnit.Change this value to display fewer or more results per page.
offset Skryté pole.Hidden field. Odsazení prvního výsledku hledání v žádosti, které slouží ke stránkování.The offset of the first search result in the request, which is used for paging. S každou novou žádostí se hodnota resetuje na 0.It's reset to 0 with each new request.

Poznámka

Rozhraní API Bingu pro vyhledávání na webu nabízí další parametry dotazu umožňující zpřesnit výsledky hledání.The Bing Web Search API offers additional query parameters to help refine search results. Tato ukázka jich používá jenom pár.This sample only uses a few. Úplný seznam dostupných parametrů najdete v tématu s referenční dokumentací k rozhraní API Bingu pro vyhledávání na webu verze 7.For a complete list of available parameters, see Bing Web Search API v7 reference.

Funkce bingSearchOptions() převede tyto možnosti tak, aby odpovídaly formátu, který vyžaduje rozhraní API Bingu pro vyhledávání.The bingSearchOptions() function converts these options to match the format required by the Bing Search API.

// Build query options from selections in the HTML form.
function bingSearchOptions(form) {

    var options = [];
    // Where option.
    options.push("mkt=" + form.where.value);
    // SafeSearch option.
    options.push("SafeSearch=" + (form.safe.checked ? "strict" : "off"));
    // Freshness option.
    if (form.when.value.length) options.push("freshness=" + form.when.value);
    var what = [];
    for (var i = 0; i < form.what.length; i++)
        if (form.what[i].checked) what.push(form.what[i].value);
    // Promote option.
    if (what.length) {
        options.push("promote=" + what.join(","));
        options.push("answerCount=9");
    }
    // Count option.
    options.push("count=" + form.count.value);
    // Offset option.
    options.push("offset=" + form.offset.value);
    // Hardcoded text decoration option.
    options.push("textDecorations=true");
    // Hardcoded text format option.
    options.push("textFormat=HTML");
    return options.join("&");
}

SafeSearch je možné nastavit na strict, moderate nebo off a výchozí nastavení pro vyhledávání na webu Bingu je moderate.SafeSearch can be set to strict, moderate, or off, with moderate being the default setting for Bing Web Search. Tento formulář používá zaškrtávací políčko, které má dva stavy.This form uses a checkbox, which has two states. V tomto fragmentu kódu je u Bezpečného hledání nastavené strict nebo off, moderate se nepoužívá.In this snippet, SafeSearch is set to strict or off, moderate isn't used.

Pokud je vybrané kterékoliv ze zaškrtávacích políček upřednostnění, přidá se k dotazu parametr answerCount.If any of the Promote checkboxes are selected, the answerCount parameter is added to the query. Když je použitý parametr promote, vyžaduje se answerCount.answerCount is required when using the promote parameter. Aby se vrátily všechny dostupné typy výsledků, je v tomto fragmentu kódu nastavená hodnota 9.In this snippet, the value is set to 9 to return all available result types.

Poznámka

Upřednostnění typu výsledku nezaručuje, že bude tento typ zahrnutý ve výsledcích hledání.Promoting a result type doesn't guarantee that it will be included in the search results. Upřednostnění ve srovnání s obvyklým hodnocením spíše zvýší hodnocení daných druhů výsledků.Rather, promotion increases the ranking of those kinds of results relative to their usual ranking. Pokud chcete omezit hledání na konkrétní typy výsledků, použijte parametr dotazu responseFilter nebo volejte konkrétnější koncový bod, jako je například Vyhledávání obrázků Bingu nebo Vyhledávání zpráv Bingu.To limit searches to particular kinds of results, use the responseFilter query parameter, or call a more specific endpoint such as Bing Image Search or Bing News Search.

Do skriptu jsou pevně zakódované parametry dotazu textDecoration a textFormat a díky tomu je hledaný termín ve výsledcích hledání napsaný tučně.The textDecoration and textFormat query parameters are hardcoded into the script, and cause the search term to be boldfaced in the search results. Tyto parametry nejsou povinné.These parameters aren't required.

Správa klíčů předplatnéhoManage subscription keys

Aby se nemusel pevně kódovat klíč předplatného rozhraní API Bingu pro vyhledávání, používá se v této ukázkové aplikaci k uložení klíče předplatného trvalé úložiště prohlížeče.To avoid hardcoding the Bing Search API subscription key, this sample app uses a browser's persistent storage to store the subscription key. Pokud není uložený žádný klíč předplatného, zobrazí se uživateli výzva, aby ho zadal.If no subscription key is stored, the user is prompted to enter one. Pokud rozhraní API klíč předplatného odmítne, zobrazí se uživateli výzva, aby klíč předplatného zadal znovu.If the subscription key is rejected by the API, the user is prompted to re-enter a subscription key.

Funkce getSubscriptionKey() používá k uložení a načtení klíče předplatného určitého uživatele funkce storeValue a retrieveValue.The getSubscriptionKey() function uses the storeValue and retrieveValue functions to store and retrieve a user's subscription key. Tyto funkce používají objekt localStorage, pokud se tato možnost podporuje, nebo soubory cookie.These functions use the localStorage object, if supported, or cookies.

// Cookie names for stored data.
API_KEY_COOKIE   = "bing-search-api-key";
CLIENT_ID_COOKIE = "bing-search-client-id";

BING_ENDPOINT = "https://api.cognitive.microsoft.com/bing/v7.0/search";

// See source code for storeValue and retrieveValue definitions.

// Get stored subscription key, or prompt if it isn't found.
function getSubscriptionKey() {
    var key = retrieveValue(API_KEY_COOKIE);
    while (key.length !== 32) {
        key = prompt("Enter Bing Search API subscription key:", "").trim();
    }
    // Always set the cookie in order to update the expiration date.
    storeValue(API_KEY_COOKIE, key);
    return key;
}

Jak jsme viděli dříve, aktivuje onsubmit při odeslání formuláře volání bingWebSearch.As we saw earlier, when the form is submitted, onsubmit fires, calling bingWebSearch. Tato funkce inicializuje a odešle žádost.This function initializes and sends the request. K ověření žádosti se při každém odeslání volá getSubscriptionKey.getSubscriptionKey is called on each submission to authenticate the request.

Na základě dotazu, řetězce možností a klíče předplatného vytvoří funkce BingWebSearch objekt XMLHttpRequest k volání koncového bodu vyhledávání na webu Bingu.Given the query, the options string, and the subscription key, the BingWebSearch function creates an XMLHttpRequest object to call the Bing Web Search endpoint.

// Perform a search constructed from the query, options, and subscription key.
function bingWebSearch(query, options, key) {
    window.scrollTo(0, 0);
    if (!query.trim().length) return false;

    showDiv("noresults", "Working. Please wait.");
    hideDivs("pole", "mainline", "sidebar", "_json", "_http", "paging1", "paging2", "error");

    var request = new XMLHttpRequest();
    var queryurl = BING_ENDPOINT + "?q=" + encodeURIComponent(query) + "&" + options;

    // Initialize the request.
    try {
        request.open("GET", queryurl);
    }
    catch (e) {
        renderErrorMessage("Bad request (invalid URL)\n" + queryurl);
        return false;
    }

    // Add request headers.
    request.setRequestHeader("Ocp-Apim-Subscription-Key", key);
    request.setRequestHeader("Accept", "application/json");
    var clientid = retrieveValue(CLIENT_ID_COOKIE);
    if (clientid) request.setRequestHeader("X-MSEdge-ClientID", clientid);

    // Event handler for successful response.
    request.addEventListener("load", handleBingResponse);

    // Event handler for errors.
    request.addEventListener("error", function() {
        renderErrorMessage("Error completing request");
    });

    // Event handler for an aborted request.
    request.addEventListener("abort", function() {
        renderErrorMessage("Request aborted");
    });

    // Send the request.
    request.send();
    return false;
}

Po úspěšné žádosti se aktivuje obslužná rutina události load a zavolá funkce handleBingResponse.Following a successful request, the load event handler fires and calls the handleBingResponse function. handleBingResponse analyzuje objekt výsledku, zobrazí výsledky a obsahuje logiku chyb pro chybné žádosti.handleBingResponse parses the result object, displays the results, and contains error logic for failed requests.

function handleBingResponse() {
    hideDivs("noresults");

    var json = this.responseText.trim();
    var jsobj = {};

    // Try to parse results object.
    try {
        if (json.length) jsobj = JSON.parse(json);
    } catch(e) {
        renderErrorMessage("Invalid JSON response");
        return;
    }

    // Show raw JSON and the HTTP request.
    showDiv("json", preFormat(JSON.stringify(jsobj, null, 2)));
    showDiv("http", preFormat("GET " + this.responseURL + "\n\nStatus: " + this.status + " " +
        this.statusText + "\n" + this.getAllResponseHeaders()));

    // If the HTTP response is 200 OK, try to render the results.
    if (this.status === 200) {
        var clientid = this.getResponseHeader("X-MSEdge-ClientID");
        if (clientid) retrieveValue(CLIENT_ID_COOKIE, clientid);
        if (json.length) {
            if (jsobj._type === "SearchResponse" && "rankingResponse" in jsobj) {
                renderSearchResults(jsobj);
            } else {
                renderErrorMessage("No search results in JSON response");
            }
        } else {
            renderErrorMessage("Empty response (are you sending too many requests too quickly?)");
        }
    }

    // Any other HTTP response is considered an error.
    else {
        // 401 is unauthorized; force a re-prompt for the user's subscription
        // key on the next request.
        if (this.status === 401) invalidateSubscriptionKey();

        // Some error responses don't have a top-level errors object, if absent
        // create one.
        var errors = jsobj.errors || [jsobj];
        var errmsg = [];

        // Display the HTTP status code.
        errmsg.push("HTTP Status " + this.status + " " + this.statusText + "\n");

        // Add all fields from all error responses.
        for (var i = 0; i < errors.length; i++) {
            if (i) errmsg.push("\n");
            for (var k in errors[i]) errmsg.push(k + ": " + errors[i][k]);
        }

        // Display Bing Trace ID if it isn't blocked by CORS.
        var traceid = this.getResponseHeader("BingAPIs-TraceId");
        if (traceid) errmsg.push("\nTrace ID " + traceid);

        // Display the error message.
        renderErrorMessage(errmsg.join("\n"));
    }
}

Důležité

Úspěšná žádost HTTP neznamená, že bylo úspěšné samotné vyhledávání.A successful HTTP request doesn't mean that the search itself succeeded. Pokud v operaci vyhledávání dojde k chybě, vrátí rozhraní API Bingu pro vyhledávání na webu stavový kód HTTP jiný než 200 a zahrne do odpovědi JSON informace o chybě.If an error occurs in the search operation, the Bing Web Search API returns a non-200 HTTP status code and includes error information in the JSON response. Pokud byla u žádosti omezena rychlost, vrátí rozhraní API prázdnou odpověď.If the request was rate-limited, the API returns an empty response.

Velká část kódu v obou předchozích funkcích je vyhrazená zpracování chyb.Much of the code in both of the preceding functions is dedicated to error handling. V následujících fázích můžou nastat chyby:Errors may occur at the following stages:

KrokStage Potenciální chybyPotential error(s) Čím se zpracujíHandled by
Vytváření objektu žádostiBuilding the request object Neplatná adresa URLInvalid URL Blok try / catchtry / catch block
Provedení žádostiMaking the request Chyby sítě, přerušená připojeníNetwork errors, aborted connections Obslužné rutiny událostí error a aborterror and abort event handlers
Provedení vyhledáváníPerforming the search Neplatná žádost, neplatný JSON, omezení rychlostiInvalid request, invalid JSON, rate limits Testy v obslužné rutině události loadTests in load event handler

Chyby se zpracují voláním renderErrorMessage().Errors are handled by calling renderErrorMessage(). Pokud odpověď úspěšně projde všemi testy chyb, volá se renderSearchResults() k zobrazení výsledků hledání.If the response passes all of the error tests, renderSearchResults() is called to display the search results.

Zobrazení výsledků hledáníDisplay search results

Pro výsledky vrácené rozhraním API Bingu pro vyhledávání na webu existují požadavky týkající se použití a zobrazení.There are use and display requirements for results returned by the Bing Web Search API. Protože odpověď může obsahovat různé typy výsledků, nestačí to k iteraci v rámci kolekce WebPages na nejvyšší úrovni.Since a response may include various result types, it isn't enough to iterate through the top-level WebPages collection. Místo toho použije ukázková aplikace k řazení výsledků podle specifikace RankingResponse.Instead, the sample app uses RankingResponse to order the results to spec.

Poznámka

Pokud chcete pouze jeden typ výsledku, použijte parametr dotazu responseFilter nebo zvažte možnost použít jeden z koncových bodů Vyhledávání Bingu, jako je například Vyhledávání obrázků Bingu.If you only want a single result type, use the responseFilter query parameter, or consider using one of the other Bing Search endpoints, such as Bing Image Search.

Každá odpověď má objekt RankingResponse, který může obsahovat až tři kolekce: pole, mainline a sidebar.Each response has a RankingResponse object that may include up to three collections: pole, mainline, and sidebar. Pokud je k dispozici pole, je to nejrelevantnější výsledek hledání a musí se zobrazit na předním místě.pole, if present, is the most relevant search result and must be prominently displayed. mainline obsahuje většinu výsledků hledání a zobrazí se hned za pole.mainline contains most of the search results, and is displayed immediately after pole. sidebar zahrnuje doplňující výsledky hledání.sidebar includes auxiliary search results. Pokud je to možné, měly by se tyto výsledky zobrazit na bočním panelu.If possible, these results should be displayed in the sidebar. Pokud není kvůli omezení obrazovky boční panel praktický, měly by se tyto výsledky zobrazit za výsledky mainline.If screen limits make a sidebar impractical, these results should appear after the mainline results.

Všechny RankingResponse zahrnují pole RankingItem, které určuje, jak mají být seřazené výsledky.Each RankingResponse includes a RankingItem array that specifies how results must be ordered. Naše ukázková aplikace používá k určení výsledku parametry answerType a resultIndex.Our sample app uses the answerType and resultIndex parameters to identify the result.

Poznámka

Existují další způsoby, jak identifikovat a řadit výsledky.There are additional ways to identify and rank results. Další informace najdete v tématu Použití řazení k zobrazení výsledků.For more information, see Using ranking to display results.

Pojďme se podívat na kód:Let's take a look at the code:

// Render the search results from the JSON response.
function renderSearchResults(results) {

    // If spelling was corrected, update the search field.
    if (results.queryContext.alteredQuery)
        document.forms.bing.query.value = results.queryContext.alteredQuery;

    // Add Prev / Next links with result count.
    var pagingLinks = renderPagingLinks(results);
    showDiv("paging1", pagingLinks);
    showDiv("paging2", pagingLinks);

    // Render the results for each section.
    for (section in {pole: 0, mainline: 0, sidebar: 0}) {
        if (results.rankingResponse[section])
            showDiv(section, renderResultsItems(section, results));
    }
}

Funkce renderResultsItems() se iteruje mezi položkami v jednotlivých kolekcích RankingResponse, mapuje každý výsledek řazení na výsledek vyhledávání pomocí hodnot answerType a resultIndex a volá příslušnou funkci vykreslení, aby se vygeneroval kód HTML.The renderResultsItems() function iterates through the items in each RankingResponse collection, maps each ranking result to a search result using the answerType and resultIndex values, and calls the appropriate rendering function to generate the HTML. Pokud nemá položka zadané resultIndex, iteruje se v rámci všech výsledků tohoto typu renderResultsItems() a pro každou položku se volá funkce vykreslení.If resultIndex isn't specified for an item, renderResultsItems() iterates through all results of that type and calls the rendering function for each item. Výsledný kód HTML se vloží do příslušného prvku <div> v index.html.The resulting HTML is inserted into the appropriate <div> element in index.html.

// Render search results from the RankingResponse object per rank response and
// use and display requirements.
function renderResultsItems(section, results) {

    var items = results.rankingResponse[section].items;
    var html = [];
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        // Collection name has lowercase first letter while answerType has uppercase
        // e.g. `WebPages` RankingResult type is in the `webPages` top-level collection.
        var type = item.answerType[0].toLowerCase() + item.answerType.slice(1);
        if (type in results && type in searchItemRenderers) {
            var render = searchItemRenderers[type];
            // This ranking item refers to ONE result of the specified type.
            if ("resultIndex" in item) {
                html.push(render(results[type].value[item.resultIndex], section));
            // This ranking item refers to ALL results of the specified type.
            } else {
                var len = results[type].value.length;
                for (var j = 0; j < len; j++) {
                    html.push(render(results[type].value[j], section, j, len));
                }
            }
        }
    }
    return html.join("\n\n");
}

Pohled na funkce rendereruReview renderer functions

V naší ukázkové aplikaci obsahuje objekt searchItemRenderers funkce, které generují kód HTML pro každý typ výsledku hledání.In our sample app, the searchItemRenderers object includes functions that generate HTML for each type of search result.

// Render functions for each result type.
searchItemRenderers = {
    webPages: function(item) { ... },
    news: function(item) { ... },
    images: function(item, section, index, count) { ... },
    videos: function(item, section, index, count) { ... },
    relatedSearches: function(item, section, index, count) { ... }
}

Důležité

Ukázková aplikace má renderery pro webové stránky, zprávy, obrázky, videa a související hledání.The sample app has renderers for web pages, news, images, videos, and related searches. Vaše aplikace bude potřebovat renderery pro každý typ výsledků, který může dostat. Ty můžou zahrnovat výpočty, návrhy pravopisu, entity, časová pásma a definice.Your application will need renderers for any type of results it may receive, which could include computations, spelling suggestions, entities, time zones, and definitions.

Některé funkce vykreslování přijímají pouze parametr item.Some of the rendering functions accept only the item parameter. Ostatní přijímají další parametry, které je možné použít k vykreslení položky různým způsobem v závislosti na kontextu.Others accept additional parameters, which can be used to render items differently based on context. Renderer, který tyto informace nepoužívá, nepotřebuje přijímat tyto parametry.A renderer that doesn't use this information doesn't need to accept these parameters.

Argumenty kontextu jsou následující:The context arguments are:

ParametrParameter PopisDescription
section Oddíl s výsledky (pole, mainline nebo sidebar), ve kterém se zobrazí položka.The results section (pole, mainline, or sidebar) in which the item appears.
index
count
K dispozici, pokud položka RankingResponse určuje, že se mají zobrazit všechny výsledky v dané kolekci. Jinak undefined.Available when the RankingResponse item specifies that all results in a given collection are to be displayed; undefined otherwise. Index položky v rámci svojí kolekce a celkový počet položek v dané kolekci.The index of the item within its collection and the total number of items in that collection. Tyto informace můžete použít k vyčíslení výsledků, generování různých kódů HTML pro první nebo poslední výsledek a tak dále.You can use this information to number the results, to generate different HTML for the first or last result, and so on.

V ukázkové aplikaci používají renderery images i relatedSearches argumenty kontextu k přizpůsobení generovaného kódu HTML.In the sample app, both the images and relatedSearches renderers use the context arguments to customize the generated HTML. Podívejme se na renderer images zblízka:Let's take a closer look at the images renderer:

searchItemRenderers = {
    // Render image result with thumbnail.
    images: function(item, section, index, count) {
        var height = 60;
        var width = Math.round(height * item.thumbnail.width / item.thumbnail.height);
        var html = [];
        if (section === "sidebar") {
            if (index) html.push("<br>");
        } else {
            if (!index) html.push("<p class='images'>");
        }
        html.push("<a href='" + item.hostPageUrl + "'>");
        var title = escape(item.name) + "\n" + getHost(item.hostPageDisplayUrl);
        html.push("<img src='"+ item.thumbnailUrl + "&h=" + height + "&w=" + width +
            "' height=" + height + " width=" + width + " title='" + title + "' alt='" + title + "'>");
        html.push("</a>");
        return html.join("");
    },
    // Other renderers are omitted from this sample...
}

Renderer obrázků:The image renderer:

  • Vypočítá velikost miniatury obrázku (šířka se liší, ale výška je pevně nastavená na 60 pixelů).Calculates the image thumbnail size (width varies, while height is fixed at 60 pixels).
  • Vloží kód HTML, který předchází výsledku obrázku na základě kontextu.Inserts the HTML that precedes the image result based on context.
  • Vytvoří značku HTML <a> odkazující na stránku, která obsahuje obrázek.Builds the HTML <a> tag that links to the page that contains the image.
  • Vytvoří značku HTML <img> k zobrazení miniatury obrázku.Builds the HTML <img> tag to display the image thumbnail.

Renderer obrázků používá proměnné section a index k zobrazení výsledků různým způsobem v závislosti na jejich umístění.The image renderer uses the section and index variables to display results differently depending on where they appear. Mezi výsledky obrázků na bočním panelu se vloží konec řádku (značka <br>) tak, aby se na bočním panelu zobrazil sloupec s obrázky.A line break (<br> tag) is inserted between image results in the sidebar, so that the sidebar displays a column of images. V dalších částech je před prvním výsledkem obrázku (index === 0) značka <p>.In other sections, the first image result (index === 0) is preceded by a <p> tag.

Velikost miniatury se používá ve značce <img> i v polích h a w v adrese URL miniatury.The thumbnail size is used in both the <img> tag and the h and w fields in the thumbnail's URL. Atributy title a alt (textový popis obrázku) se vytvářejí z názvu obrázku a názvu hostitele v adrese URL.The title and alt attributes (a textual description of the image) are constructed from the image's name and the hostname in the URL.

Tady je příklad zobrazení obrázků v ukázkové aplikaci:Here's an example of how images are displayed in the sample app:

[Výsledky obrázků Bingu]

Zachování ID klientaPersist the client ID

Odpovědi z rozhraní API Bingu pro vyhledávání můžou zahrnovat hlavičku X-MSEdge-ClientID, která by se měla s každou následující žádostí posílat zpátky do rozhraní API.Responses from the Bing search APIs may include a X-MSEdge-ClientID header that should be sent back to the API with each successive request. Pokud používá vaše aplikace více než jedno rozhraní API Bingu pro vyhledávání na webu, je nutné poslat s každou žádostí napříč službami stejné ID klienta.If more than one of the Bing Search APIs is used by your app, make sure the same client ID is sent with each request across services.

Poskytnutí hlavičky X-MSEdge-ClientID umožňuje rozhraním API Bingu spojit si všechna vyhledávání určitého uživatele.Providing the X-MSEdge-ClientID header allows the Bing APIs to associate a user's searches. Zaprvé to umožňuje, aby vyhledávací web Bing použil při vyhledávání minulý kontext a našel výsledky, které lépe vyhoví žádosti.First, it allows the Bing search engine to apply past context to searches to find results that better satisfy the request. Pokud uživatel v minulosti vyhledával třeba výrazy týkající se lodí, může pozdější vyhledání „uzlů“ přednostně vrátit informace o uzlech používaných při plavbě lodí.If a user has previously searched for terms related to sailing, for example, a later search for "knots" might preferentially return information about knots used in sailing. Za druhé může Bing náhodně vybírat uživatele k vyzkoušení nových funkcí, než budou všeobecně dostupné.Second, Bing may randomly select users to experience new features before they are made widely available. Poskytnutí stejného ID klienta s každou žádostí zajistí, že uživatelé vybraní k tomu, aby danou funkci viděli, ji uvidí vždy.Providing the same client ID with each request ensures that users who have been chosen to see a feature will always see it. Bez ID klienta může uživatel funkci ve svých výsledcích hledání zdánlivě náhodně někdy vidět a jindy ne.Without the client ID, the user might see a feature appear and disappear, seemingly at random, in their search results.

Zásady zabezpečení prohlížeče, jako je například sdílení prostředků mezi zdroji (CORS), můžou zabránit ukázkové aplikaci v přístupu k hlavičce X-MSEdge-ClientID.Browser security policies, such as Cross-Origin Resource Sharing (CORS), may prevent the sample app from accessing the X-MSEdge-ClientID header. K tomuto omezení dochází, když má odpověď na vyhledávání jiný zdroj než stránka, která o ni požádala.This limitation occurs when the search response has a different origin from the page that requested it. V produkčním prostředí je potřeba tyto zásady vyřešit hostováním skriptu na straně serveru, který provádí volání rozhraní API ve stejné doméně jako webová stránka.In a production environment, you should address this policy by hosting a server-side script that does the API call on the same domain as the Web page. Protože tento skript má stejný původ jako webová stránka, hlavička X-MSEdge-ClientID je pak pro JavaScript dostupná.Since the script has the same origin as the Web page, the X-MSEdge-ClientID header is then available to JavaScript.

Poznámka

Při tvorbě webové aplikace byste měli provádět žádost na straně serveru tak jako tak.In a production Web application, you should perform the request server-side anyway. Jinak musí být klíč předplatného rozhraní API Bingu pro vyhledávání součástí webové stránky, kde je k dispozici každému, kdo si zobrazí zdroj.Otherwise, your Bing Search API subscription key must be included in the web page, where it's available to anyone who views source. Účtuje se veškeré využívání vašeho klíče předplatného rozhraní API, dokonce i žádosti provedené neoprávněnými stranami, proto je důležité klíč nezveřejňovat.You are billed for all usage under your API subscription key, even requests made by unauthorized parties, so it is important not to expose your key.

Pro účely vývoje můžete žádost provést prostřednictvím proxy serveru CORS.For development purposes, you can make a request through a CORS proxy. Odpověď z takového typu proxy serveru má hlavičku Access-Control-Expose-Headers, která přidává hlavičky odpovědí na seznam povolených a zpřístupňuje je pro JavaScript.The response from this type of proxy has an Access-Control-Expose-Headers header that whitelists response headers and makes them available to JavaScript.

Nainstalovat proxy server CORS a povolit naší ukázkové aplikaci přístup k hlavičce ID klienta je snadné.It's easy to install a CORS proxy to allow our sample app to access the client ID header. Spusťte tento příkaz:Run this command:

npm install -g cors-proxy-server

V dalším kroku změňte koncový bod vyhledávání na webu Bingu v script.js na:Next, change the Bing Web Search endpoint in script.js to:

http://localhost:9090/https://api.cognitive.microsoft.com/bing/v7.0/search

Spuštění proxy serveru CORS pomocí tohoto příkazu:Start the CORS proxy with this command:

cors-proxy-server

Při používání ukázkové aplikace nechejte otevřené příkazové okno. Pokud okno zavřete, proxy server se zastaví.Leave the command window open while you use the sample app; closing the window stops the proxy. V rozbalitelné části hlaviček protokolu HTTP pod výsledky hledání byste měli vidět hlavičku X-MSEdge-ClientID.In the expandable HTTP Headers section below the search results, the X-MSEdge-ClientID header should be visible. Ověřte, že je u všech žádostí stejná.Verify that it's the same for each request.

Další postupNext steps