Självstudier: Skapa en enkelsidig app med hjälp av API:et för webbsökning i BingTutorial: Create a single-page app using the Bing Web Search API

Den här ensidesappen visar hur du hämtar, analyserar och visar sökresultat från API för webbsökning i Bing.This single-page app demonstrates how to retrieve, parse, and display search results from the Bing Web Search API. Självstudien använder formaterad HTML och CSS och fokuserar på JavaScript-koden.The tutorial uses boilerplate HTML and CSS, and focuses on the JavaScript code. HTML-, CSS- och JS-filer finns på GitHub med snabbstartsinstruktioner.HTML, CSS, and JS files are available on GitHub with quickstart instructions.

Den här exempelappen kan:This sample app can:

  • Anropa API för webbsökning i Bing med sökalternativCall the Bing Web Search API with search options
  • Visa webb, bild, nyheter och videoresultatDisplay web, image, news, and video results
  • Sidnumrera resultatPaginate results
  • Hantera prenumerationsnycklarManage subscription keys
  • Hantera felHandle errors

För att använda den här appen krävs ett Azure Cognitive Services-konto med API:er för Bing-sökresultat.To use this app, an Azure Cognitive Services account with Bing Search APIs is required. Om du inte har ett konto kan du använda den kostnadsfria utvärderingsversionen för att hämta en prenumerationsnyckel.If you don't have an account, you can use the free trial to get a subscription key.

Nödvändiga komponenterPrerequisites

Här följer några saker som du kan behöva för att köra appen:Here are a few things that you'll need to run the app:

  • Node.js 8 eller senareNode.js 8 or later
  • En prenumerationsnyckelA subscription key

Hämta källkoden och installera beroendenGet the source code and install dependencies

Det första steget är att klona lagringsplatsen med exempelappens källkod.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

Kör sedan npm install.Then run npm install. För den här självstudien är Express.js det enda beroendet.For this tutorial, Express.js is the only dependency.

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

AppkomponenterApp components

Exempelappen som vi bygger består av fyra delar:The sample app we're building is made up of four parts:

  • bing-web-search.js - Vår Express.js-app.bing-web-search.js - Our Express.js app. Den hanterar begäran/svarslogik och routning.It handles request/response logic and routing.
  • public/index.html - Stommen i vår app. Den definierar hur data ska visas för användaren.public/index.html - The skeleton of our app; it defines how data is presented to the user.
  • public/css/styles.css -Definierar sidans format, såsom teckensnitt, färger, textstorlek.public/css/styles.css - Defines page styles, such as fonts, colors, text size.
  • public/js/scripts.js - Innehåller logik för att göra begäranden till API för webbsökning i Bing, hantera prenumerationsnycklar, hantera och parsa svar och visa resultat.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.

Den här självstudien fokuserar på scripts.js och den logik som krävs för att anropa API för webbsökning i Bing och hantera svaret.This tutorial focuses on scripts.js and the logic required to call the Bing Web Search API and handle the response.

HTML-formulärHTML form

index.html innehåller ett formulär som gör det möjligt för användare att söka efter och välja alternativ för sökning.The index.html includes a form that enables users to search and select search options. Attributet onsubmit utlöses när formuläret skickas och anropar den bingWebSearch()-metod som definieras i scripts.js.The onsubmit attribute fires when the form is submitted, calling the bingWebSearch() method defined in scripts.js. Den tar tre argument:It takes three arguments:

  • SökfrågaSearch query
  • Valda alternativSelected options
  • PrenumerationsnyckelSubscription key
<form name="bing" onsubmit="return bingWebSearch(this.query.value,
    bingSearchOptions(this), getSubscriptionKey())">

FrågealternativQuery options

HTML-formuläret innehåller alternativ som mappar till frågeparametrar i API för webbsökning i Bing v7.The HTML form includes options that map to query parameters in the Bing Web Search API v7. Den här tabellen innehåller en detaljerad analys av hur användarna kan filtrera sökresultat med hjälp av exempelappen:This table provides a breakdown of how users can filter search results using the sample app:

ParameterParameter BeskrivningDescription
query Ett textfält för att ange en frågesträng.A text field to enter a query string.
where En nedrullningsbar meny för att välja marknaden (plats och språk).A drop-down menu to select the market (location and language).
what Kryssrutorna för att flytta upp specifika resultattyper.Checkboxes to promote specific result types. Uppgradera bilder ökar till exempel rangordningen av bilder i sökresultaten.Promoting images, for example, increases the ranking of images in search results.
when En nedrullningsbar meny som används för att begränsa sökresultaten till dagens datum, den här veckan eller den här månaden.A drop-down menu that allows the user to limit the search results to today, this week, or this month.
safe En kryssruta för att aktivera Bing SafeSearch som filtrerar ut innehåll som är olämpligt för barn.A checkbox to enable Bing SafeSearch, which filters out adult content.
count Dolt fält.Hidden field. Antal sökresultat som returneras för varje begäran.The number of search results to return on each request. Ändra det här värdet om du vill visa färre eller fler resultat per sida.Change this value to display fewer or more results per page.
offset Dolt fält.Hidden field. Förskjutningen av det första sökresultatet i begäran, vilket används för växling.The offset of the first search result in the request, which is used for paging. Den återställs till 0 för varje ny begäran.It's reset to 0 with each new request.

Anteckning

API för webbsökning i Bing erbjuder ytterligare frågeparametrar för att begränsa sökresultaten.The Bing Web Search API offers additional query parameters to help refine search results. I det här exemplet används bara några få.This sample only uses a few. En fullständig lista över tillgängliga parametrar finns i referensen API för webbsökning i Bing v7.For a complete list of available parameters, see Bing Web Search API v7 reference.

Funktionen bingSearchOptions() konverterar dessa alternativ för att matcha det format som krävs av API för sökning i Bing.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 kan anges till strict, moderate eller off, med moderate som standardinställningen för webbsökning i Bing.SafeSearch can be set to strict, moderate, or off, with moderate being the default setting for Bing Web Search. Det här formuläret använder en kryssruta som har två tillstånd.This form uses a checkbox, which has two states. I det här kodfragmentet anges SafeSearch till strict eller off, moderate används inte.In this snippet, SafeSearch is set to strict or off, moderate isn't used.

Om något av kryssrutorna befordra är markerade har parametern answerCount lagts till i frågan.If any of the Promote checkboxes are selected, the answerCount parameter is added to the query. answerCount krävs när du använder parametern promote.answerCount is required when using the promote parameter. I det här kodfragmentet anges värdet till 9 för att returnera alla tillgängliga resultattyper.In this snippet, the value is set to 9 to return all available result types.

Anteckning

Att uppgradera en resultattyp garanterar inte att den tas med i sökresultatet.Promoting a result type doesn't guarantee that it will be included in the search results. I stället ökar befordran rangordningen för denna typ av resultat i förhållande till deras vanliga rangordning.Rather, promotion increases the ranking of those kinds of results relative to their usual ranking. För att begränsa sökningen till olika typer av resultat, använder du frågeparametern responseFilter eller anropar en mer specifik slutpunkt för bildsökning i Bing t.ex nyhetssökning i Bing.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.

Frågeparametrarna textDecoration och textFormat är hårdkodade i skriptet och gör så att söktermen är i fetstilt i sökresultatet.The textDecoration and textFormat query parameters are hardcoded into the script, and cause the search term to be boldfaced in the search results. Dessa parametrar behövs inte.These parameters aren't required.

Hantera prenumerationsnycklarManage subscription keys

För att undvika hårdkodning av prenumerationsnyckeln för API:er för sökning i Bing använder den här exempelappen beständig lagring i en webbläsare för att lagra prenumerationsnyckeln.To avoid hardcoding the Bing Search API subscription key, this sample app uses a browser's persistent storage to store the subscription key. Om ingen prenumerationsnyckel lagras, uppmanas användaren att ange en.If no subscription key is stored, the user is prompted to enter one. Om prenumerationsnyckeln har avvisats av API:et, ombeds användaren att ange en prenumerationsnyckel på nytt.If the subscription key is rejected by the API, the user is prompted to re-enter a subscription key.

Funktionen getSubscriptionKey() använder funktionerna storeValue och retrieveValue för att lagra och hämta en användares prenumerationsnyckel.The getSubscriptionKey() function uses the storeValue and retrieveValue functions to store and retrieve a user's subscription key. Dessa funktioner använder objektet localStorage, om det stöds, eller cookies.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;
}

Som vi såg tidigare, när formuläret skickas utlöses onsubmit och anropar bingWebSearch.As we saw earlier, when the form is submitted, onsubmit fires, calling bingWebSearch. Den här funktionen initierar och skickar en begäran.This function initializes and sends the request. getSubscriptionKey anropas vid varje överföring för att autentisera begäran.getSubscriptionKey is called on each submission to authenticate the request.

Baserat på frågan, alternativsträngen och prenumerationsnyckeln, skapar funktionen BingWebSearch ett XMLHttpRequest-objekt för att anropa slutpunkten för webbsökning i Bing.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;
}

Efter en lyckad begäran, utlöses load-händelsehanteraren och anropar funktionen handleBingResponse.Following a successful request, the load event handler fires and calls the handleBingResponse function. handleBingResponse parsar resultatobjektet, visar resultaten och innehåller fellogik för misslyckade förfrågningar.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"));
    }
}

Viktigt

En lyckad HTTP-begäran betyder inte att själva sökningen lyckades.A successful HTTP request doesn't mean that the search itself succeeded. Om ett fel uppstår i sökåtgärden returnerar API för webbsökning i Bing en icke-200-HTTP-statuskod och inkluderar felinformation i JSON-svaret.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. Om begäran var begränsad returnerar API:et ett tomt svar.If the request was rate-limited, the API returns an empty response.

En stor del av koden i de båda föregående funktionerna är dedikerade för felhantering.Much of the code in both of the preceding functions is dedicated to error handling. Fel kan inträffa i följande steg:Errors may occur at the following stages:

FasStage Potentiella felPotential error(s) Hanterat avHandled by
Skapa objektbegäranBuilding the request object Ogiltig URLInvalid URL try / catch blockeratry / catch block
Skapa begäranMaking the request Nätverksfel, avbrutna anslutningarNetwork errors, aborted connections Händelsehanterare för error och aborterror and abort event handlers
Genomföra sökningenPerforming the search Ogiltig begäran, ogiltig JSON, hastighetsbegränsningarInvalid request, invalid JSON, rate limits tests i load händelsehanterareTests in load event handler

Fel hanteras genom att anropa renderErrorMessage().Errors are handled by calling renderErrorMessage(). Om svaret klarar samtliga av dessa feltest, anropas renderSearchResults() för att visa sökresultaten.If the response passes all of the error tests, renderSearchResults() is called to display the search results.

Visa sökresultatDisplay search results

Det finns användar- och visningskrav för resultaten som returnerades av API för webbsökning i Bing.There are use and display requirements for results returned by the Bing Web Search API. Eftersom ett svar kan innehålla olika resultattyper, räcker det inte att gå igenom den översta WebPages-samlingen.Since a response may include various result types, it isn't enough to iterate through the top-level WebPages collection. I stället använder exempelappen RankingResponse för att sortera resultaten till specifikationen.Instead, the sample app uses RankingResponse to order the results to spec.

Anteckning

Om du bara vill ha en resultattyp, använder du frågeparametern responseFilter eller överväger att använda en av de andra slutpunkterna för sökning i Bing, till exempel bildsökning i Bing.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.

Varje svar har ett RankingResponse-objekt som kan innehålla upp till tre samlingar: pole, mainline och sidebar.Each response has a RankingResponse object that may include up to three collections: pole, mainline, and sidebar. pole, om det finns, är det mest relevanta sökresultatet och måste visas på en framträdande plats.pole, if present, is the most relevant search result and must be prominently displayed. mainline innehåller de flesta av sökresultaten och visas omedelbart efter pole.mainline contains most of the search results, and is displayed immediately after pole. sidebar innehåller extra sökresultat.sidebar includes auxiliary search results. Om möjligt ska de här resultaten visas i sidopanelen.If possible, these results should be displayed in the sidebar. Om skärmens gränser gör det opraktiskt med en sidopanel, visas de här resultaten efter mainline-resultaten.If screen limits make a sidebar impractical, these results should appear after the mainline results.

Varje RankingResponse innehåller en RankingItem-matris som anger hur resultat måste ordnas.Each RankingResponse includes a RankingItem array that specifies how results must be ordered. Vårt exempel använder parametrarna answerType och resultIndex för att identifiera resultatet.Our sample app uses the answerType and resultIndex parameters to identify the result.

Anteckning

Det finns andra sätt att identifiera och rangordna resultat.There are additional ways to identify and rank results. Mer information finns i Använda rangordning för att visa resultat.For more information, see Using ranking to display results.

Låt oss ta en titt på koden: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));
    }
}

Funktionen renderResultsItems() går igenom objekten i varje RankingResponse-samling, mappar varje rangordningsresultat till ett sökresultat med hjälp av värdena answerType och resultIndex och anropar lämplig renderingsfunktion för att generera 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. Om resultIndex inte har angetts för ett objekt, går renderResultsItems() igenom alla resultat av denna typ och anropar renderingsfunktionen för varje objekt.If resultIndex isn't specified for an item, renderResultsItems() iterates through all results of that type and calls the rendering function for each item. Resulterande HTML matas in i aktuellt <div>-element i 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");
}

Granska renderingsfunktionerReview renderer functions

I vår exempelapp innehåller searchItemRenderers-objektet funktioner som genererar HTML för varje typ av sökresultat.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) { ... }
}

Viktigt

Exempelappen har renderare för webbsidor, nyheter, bilder, videoklipp och relaterade sökningar.The sample app has renderers for web pages, news, images, videos, and related searches. Ditt program behöver renderare för alla typer av resultat det kan få, vilket kan omfatta beräkningar, stavningsförslag, entiteter, tidszoner och definitioner.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ågra av funktionerna för rendering accepterar endast parametern item.Some of the rendering functions accept only the item parameter. Andra accepterar extraparametrar som kan användas för att återge objekt på olika sätt beroende på kontext.Others accept additional parameters, which can be used to render items differently based on context. Ett renderingsprogram som inte använder den här informationen behöver inte godkänna dessa parametrar.A renderer that doesn't use this information doesn't need to accept these parameters.

Kontextargumenten är:The context arguments are:

ParameterParameter BeskrivningDescription
section Resultatavsnittet (pole, mainline, eller sidebar) i vilket objektet visas.The results section (pole, mainline, or sidebar) in which the item appears.
index
count
Tillgängligt när RankingResponse-objektet anger att alla resultat i en viss samling ska visas; undefined annars.Available when the RankingResponse item specifies that all results in a given collection are to be displayed; undefined otherwise. Index för objektet i en samling och det totala antalet objekt i samlingen.The index of the item within its collection and the total number of items in that collection. Du kan använda den här informationen för att numrera resultaten för att generera olika HTML för det första eller sista resultatet och så vidare.You can use this information to number the results, to generate different HTML for the first or last result, and so on.

I exempelappen, använder både renderare images och relatedSearches kontextargumenten för att anpassa genererad HTML.In the sample app, both the images and relatedSearches renderers use the context arguments to customize the generated HTML. Låt oss ta en närmare titt på renderare images: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...
}

Bildåtergivare:The image renderer:

  • Beräknar storleken på miniatyrbilderna (bredd varierar, medan höjd är högst 60 bildpunkter).Calculates the image thumbnail size (width varies, while height is fixed at 60 pixels).
  • Infogar den HTML som föregår bildresultatet baserat på kontext.Inserts the HTML that precedes the image result based on context.
  • Skapar en HTML <a>-tagg som länkar till den sida som innehåller bilden.Builds the HTML <a> tag that links to the page that contains the image.
  • Skapar en HTML <img>-tagg för att visa miniatyrbilden.Builds the HTML <img> tag to display the image thumbnail.

Bildåtergivning använder variablerna section och index för att visa resultat på olika sätt beroende på var de förekommer.The image renderer uses the section and index variables to display results differently depending on where they appear. En radbrytning (<br>-tagg) infogas mellan bildresultat i sidopanelen, så att sidopanelen visar en kolumn med bilder.A line break (<br> tag) is inserted between image results in the sidebar, so that the sidebar displays a column of images. I andra avsnitt, föregås det första bildresultatet (index === 0) av en <p>-tagg.In other sections, the first image result (index === 0) is preceded by a <p> tag.

Storlek på miniatyrbilderna används i både <img>-taggen och fälten h och w i miniatyrbildens webbadress.The thumbnail size is used in both the <img> tag and the h and w fields in the thumbnail's URL. Attribut title och alt (en textbeskrivning av bilden) skapas från bildens namn och värdnamnet i URL:en.The title and alt attributes (a textual description of the image) are constructed from the image's name and the hostname in the URL.

Här är ett exempel på hur bilder visas i exempelappen:Here's an example of how images are displayed in the sample app:

[Bing bildresultat]

Spara klient-ID:tPersist the client ID

Svar från API:er för sökning i Bing kan innehålla ett X-MSEdge-ClientID-huvud som ska skickas tillbaka till API:et med varje efterföljande begäran.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. Om mer än ett av API:erna för sökning i Bing används av din app, kontrollerar du att samma klient-ID har skickats med varje begäran över tjänster.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.

Genom att tillhandahålla X-MSEdge-ClientID-huvudet kan Bing-API:er associera en användares sökningar.Providing the X-MSEdge-ClientID header allows the Bing APIs to associate a user's searches. Först hjälper Bing-sökmotorn till med att tillämpa den senaste kontext på sökningarna för att hitta resultat som bättre tillfredsställer begäran.First, it allows the Bing search engine to apply past context to searches to find results that better satisfy the request. Om en användare tidigare har sökt efter termer som exempelvis relaterar till segling kan en senare sökning efter ”knopar” returnera information om knopar som används vid segling.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. Därefter väljer Bing slumpmässigt ut användare som ska prova nya funktioner innan de blir allmänt tillgängliga.Second, Bing may randomly select users to experience new features before they are made widely available. Genom att tillhandahålla samma klient-ID med varje begäran säkerställs att användare som har valts för att se en funktion alltid ser den.Providing the same client ID with each request ensures that users who have been chosen to see a feature will always see it. Utan klient-ID kan användaren se en funktion som sedan försvinner, till synes slumpmässigt, i sökresultatet.Without the client ID, the user might see a feature appear and disappear, seemingly at random, in their search results.

Webbläsarens säkerhetsprinciper, till exempel resursdelning för korsande ursprung (CORS), kan hindra exempelappen från att komma åt rubriken 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. Den här begränsningen uppstår när söksvaret har ett annat ursprung än sidan som begärt det.This limitation occurs when the search response has a different origin from the page that requested it. I en produktionsmiljö bör du hantera den här principen genom att lägga upp ett serverskript som gör API-anrop på samma domän som webbsidan.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. Eftersom skriptet har samma ursprung som webbsidan är sedan X-MSEdge-ClientID-huvudet tillgängligt för JavaScript.Since the script has the same origin as the Web page, the X-MSEdge-ClientID header is then available to JavaScript.

Anteckning

Du bör utföra begäran på serversidan i ett produktionsklart webbprogram ändå.In a production Web application, you should perform the request server-side anyway. I annat fall måste API-prenumerationsnyckeln för Bing-sökning inkluderas i webbsidan där den är tillgänglig för alla som visar källan.Otherwise, your Bing Search API subscription key must be included in the web page, where it's available to anyone who views source. Du debiteras för all användning under din API-prenumerationsnyckel, även begäranden som görs av obehöriga personer, så det är viktigt att inte exponera nyckeln.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.

För utvecklingssyften kan du göra en begäran via en proxyserver för CORS.For development purposes, you can make a request through a CORS proxy. Svaret från denna typ av proxy har ett Access-Control-Expose-Headers-huvud som vitlistar svarshuvuden och gör dem tillgängliga för 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.

Det är enkelt att installera en CORS-proxy för att tillåta att exempelappen får åtkomst till klientens ID-huvud.It's easy to install a CORS proxy to allow our sample app to access the client ID header. Kör följande kommando:Run this command:

npm install -g cors-proxy-server

Ändra slutpunkten för webbsökning i Bing i script.js till:Next, change the Bing Web Search endpoint in script.js to:

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

Starta CORS-proxyn med det här kommandot:Start the CORS proxy with this command:

cors-proxy-server

Lämna kommandofönstret öppet medan du använder exempelappen. Om du stänger fönstret stoppas proxyn.Leave the command window open while you use the sample app; closing the window stops the proxy. I avsnittet utbyggbara HTTP-huvuden under sökresultaten bör sidhuvudet X-MSEdge-ClientID visas.In the expandable HTTP Headers section below the search results, the X-MSEdge-ClientID header should be visible. Kontrollera att det är samma för varje begäran.Verify that it's the same for each request.

Nästa stegNext steps