검색

사용자가 입력한 검색어로 로컬 또는 원격 소스에서 결과를 찾아 보여 주는 컴포넌트예요. URL 템플릿과 UI 상태 관리를 위해 Semantic의 API 동작 위에 만들어져 있어요.

출처: 문서

본문

유형 (Types)

표준 (Standard)

검색은 결과 집합을 표시할 수 있어요.

지우기 가능 (Clearable)

검색은 이전 검색어를 취소할 수 있도록 제거 아이콘을 표시할 수 있어요.

카테고리 (Category)

검색은 원격 콘텐츠의 결과를 카테고리별로 정렬해 표시할 수 있어요.

가로 카테고리 (Horizontal Category)

각 결과 위에 카테고리 이름을 가로로 표시할 수도 있어요.

로컬 검색 (Local Search)

검색은 정적 로컬 소스 안에서 결과를 찾을 수 있어요.

$('.ui.search')
          .search({
            source: content
          })
        ;
      
      
      var content = [
        { title: 'Andorra' },
        { title: 'United Arab Emirates' },
        { title: 'Afghanistan' },
        { title: 'Antigua' },
        { title: 'Anguilla' },
        { title: 'Albania' },
        { title: 'Armenia' },
        { title: 'Netherlands Antilles' },
        { title: 'Angola' },
        { title: 'Argentina' },
        { title: 'American Samoa' },
        { title: 'Austria' },
        { title: 'Australia' },
        { title: 'Aruba' },
        { title: 'Aland Islands' },
        { title: 'Azerbaijan' },
        { title: 'Bosnia' },
        { title: 'Barbados' },
        { title: 'Bangladesh' },
        { title: 'Belgium' },
        { title: 'Burkina Faso' },
        { title: 'Bulgaria' },
        { title: 'Bahrain' },
        { title: 'Burundi' }
        // etc
      ];

로컬 카테고리 검색 (Local Category Search)

검색은 정적 로컬 소스 안에서 카테고리 결과를 찾을 수 있어요.

$('.ui.search')
          .search({
            type: 'category',
            source: categoryContent
          })
        ;
      
      
      var categoryContent = [
        { category: 'South America', title: 'Brazil' },
        { category: 'South America', title: 'Peru' },
        { category: 'North America', title: 'Canada' },
        { category: 'Asia', title: 'South Korea' },
        { category: 'Asia', title: 'Japan' },
        { category: 'Asia', title: 'China' },
        { category: 'Europe', title: 'Denmark' },
        { category: 'Europe', title: 'England' },
        { category: 'Europe', title: 'France' },
        { category: 'Europe', title: 'Germany' },
        { category: 'Africa', title: 'Ethiopia' },
        { category: 'Africa', title: 'Nigeria' },
        { category: 'Africa', title: 'Zimbabwe' },
      ];

발음 구별 부호 무시하기 (Search ignoring Diacritics)

검색 필드는 검색하는 동안 모든 발음 구별 부호(어큐트 등)를 무시하도록 허용할 수 있어요.

$('#diacriticsexample')
            .search({
                ignoreDiacritics: true,
                fullTextSearch:'exact',
                source: [
                    { title: 'André'},
                    { title: 'Bokmål'},
                    { title: 'café'},
                    { title: 'cafetería'},
                    { title: 'château'},
                    { title: 'décolleté'},
                    { title: 'Élysée'},
                    { title: 'Fräulein'},
                    { title: 'garçon'},
                    { title: 'háček'},
                    { title: 'inrō'},
                    { title: 'jūjutsu'},
                    { title: 'kroužek'},
                    { title: 'La Niña'},
                    { title: 'Māori'},
                    { title: 'négligée'},
                    { title: 'pączki'},
                    { title: 'Québec'},
                    { title: 'ragoût'},
                    { title: 'Škoda'},
                    { title: 'takahē'},
                    { title: 'über'},
                    { title: 'voilà'},
                    { title: 'whekī'},
                    { title: 'c Zoë'}
                ]
            })
        ;

검색 매치 강조하기 (Highlight search matches)

검색 필드는 검색 결과 안에서 일치하는 문자열을 강조할 수 있어요.

$('#highlightexample')
            .search({
                highlightMatches: true,
                source: [
                    { title: 'Andorra' },
                    { title: 'United Arab Emirates' },
                    { title: 'Afghanistan' },
                    { title: 'Antigua' },
                    { title: 'Anguilla' },
                    { title: 'Albania' },
                    { title: 'Armenia' },
                    { title: 'Netherlands Antilles' },
                    { title: 'Angola' },
                    { title: 'Argentina' },
                    { title: 'American Samoa' },
                    { title: 'Austria' },
                    { title: 'Australia' },
                    { title: 'Aruba' },
                    { title: 'Aland Islands' },
                    { title: 'Azerbaijan' },
                    { title: 'Bosnia' },
                    { title: 'Barbados' },
                    { title: 'Bangladesh' },
                    { title: 'Belgium' },
                    { title: 'Burkina Faso' },
                    { title: 'Bulgaria' },
                    { title: 'Bahrain' },
                    { title: 'Burundi' }
                ]
            })
        ;
<!-- Coming in 2.2

Selection

A search can used inside a form to store a selection

$('.ui.search')
          .search{
            source: countries
          })
        ;

-->

상태 (States)

로딩 (Loading)

검색은 로딩 표시기를 보여 줄 수 있어요.

변형 (Variations)

비활성화 (Disabled)

검색은 현재 상호작용할 수 없음을 표시할 수 있어요.

스크롤 (Scrolling)

검색 결과를 스크롤할 수 있어요.

You can also use resizable scrolling and a native resize drag handler will appear to the bottom right of the results. This needs a modern browser, so does not work in IE11 or legacy Edge.

리사이즈 가능한 스크롤을 사용할 수도 있어요. 그러면 결과의 오른쪽 아래에 네이티브 리사이즈 드래그 핸들이 나타나요. 이 기능은 최신 브라우저가 필요해서 IE11이나 레거시 Edge에서는 동작하지 않아요.

높이 (Height)

검색은 기본 높이의 0.75배로 매우 짧게 만들어 더 많은 결과를 한눈에 볼 수 있게 할 수 있어요.

플루이드 (Fluid)

검색 결과가 컨테이너의 너비를 전부 차지하게 할 수 있어요.

정렬 (Aligned)

검색 결과를 왼쪽 또는 오른쪽 컨테이너 가장자리에 정렬할 수 있어요.

크기 (Size)

검색 크기를 다르게 할 수 있어요.

초기화 (Initializing)

  Search는 URL 템플릿과 UI 상태 관리를 위해 Semantic의 [API](/behaviors/api.html) 동작 위에 만들어져 있어요. API 설정을 조정하는 방법에 대한 자세한 내용은 API 문서를 확인해 주세요.

자동 라우팅 (Automatic Routing)

기본적으로 검색은 'search'라는 이름의 API 엔드포인트로 자동 라우팅돼요.

  // 기본 엔드포인트 /search/{query}로 초기화
  $('.ui.search')
    .search({
      type: 'category'
    })
  ;

이름 있는 URL (Named URL)

URL, 콜백 설정을 조정하거나 다른 API 동작을 지정하도록 사용자 정의 API 설정을 지정할 수 있어요.

  $('.ui.search')
    .search({
      // apiSettings를 조작해 검색 엔드포인트를 사용자 정의 엔드포인트로 변경
      apiSettings: {
        url: 'custom-search/?q={query}'
      },
      type: 'category'
    })
  ;

로컬 객체 (Local Object)

로컬 검색 결과로 특정 javascript 객체 리터럴의 지정된 속성들 안에서 일치하는 값을 검색할 수 있어요.

searchFields 설정으로 어떤 필드를 검색할 수 있는지 지정할 수 있어요.

  // 검색 가능한 객체들의 배열/객체 전체를 검색
  var
    content = [
      {
        title: 'Horse',
        description: 'An Animal',
      },
      {
        title: 'Cow',
        description: 'Another Animal',
      }
    ]
  ;
  $('.ui.search')
    .search({
      source : content,
      searchFields   : [
        'title'
      ],
      fullTextSearch: false
    })
  ;

서버 응답 (Server Responses)

서버 응답이 올바른 HTTP 코드를 반환하더라도 실제로 성공했는지 판단하려면 `success: true` 같은 최상위 속성을 추가하고 API의 `successTest` 매개변수를 사용하는 것도 고려해 볼 수 있어요.

표준 (Standard)

  {
    "results": [
      {
        "title": "Result Title",
        "url": "/optional/url/on/click",
        "image": "optional-image.jpg",
        "alt": "optional alt attribute text for the given image",
        "price": "Optional Price",
        "description": "Optional Description"
      },
      {
        "title": "Result Title",
        "description": "Result Description"
      }
    ],
    // results 아래의 선택적 action
    "action": {
      "url": '/path/to/results',
      "text": "View all 202 results"
    }
  }

카테고리 (Category)

  {
    "results": {
      "category1": {
        "name": "Category 1",
        "results": [
          {
            "title": "Result Title",
            "url": "/optional/url/on/click",
            "image": "optional-image.jpg",
            "price": "Optional Price",
            "description": "Optional Description"
          },
          {
            "title": "Result Title",
            "url": "/optional/url/on/click",
            "image": "optional-image.jpg",
            "price": "Optional Price",
            "description": "Optional Description"
          }
        ]
      },
      "category2": {
        "name": "Category 2",
        "results": [
          {
            "title": "Result Title",
            "url": "/optional/url/on/click",
            "image": "optional-image.jpg",
            "price": "Optional Price",
            "description": "Optional Description"
          }
        ]
      }
    },
    // results 아래의 선택적 action
    "action": {
      "url": '/path/to/results',
      "text": "View all 202 results"
    }
  }

결과 가져오기 (Retrieving Results)

고유 ID (Unique IDs)

결과에 id 속성이 포함되지 않으면 결과가 반환될 때 각 결과마다 키가 자동으로 생성돼요.

ID는 결과 안의 위치로 생성돼요. 예를 들어 첫 번째 요소는 id 1을 받고, 첫 번째 카테고리 결과는 id a1을 받아요.

그런 다음 id나 검색 결과 제목을 get result(value)와 함께 사용해 결과 객체를 반환할 수 있어요.

  // 제목이 cat인 현재 검색 결과를 가져옴
  $('.ui.search')
    .search('get result', 'cat')
  ;
  // 카테고리 검색으로 첫 번째 카테고리의 첫 번째 결과를 가져옴
  $('.ui.search')
    .search('get result', 'a1')
  ;
  // 표준 검색으로 첫 번째 결과를 가져옴
  $('.ui.search')
    .search('get result', '1')
  ;

동작 (Behaviors)

다음 모든 동작들을 다음 구문으로 호출할 수 있어요:

$('.your.element')
  .search('behavior name', argumentOne, argumentTwo)
;

  Behavior / Description

    query (callback)
    검색 입력에 현재 설정된 값을 검색해요.

    display message(text, type)
    텍스트와 함께 type에 일치하는 템플릿을 사용해 검색 결과에 메시지를 표시해요.

    cancel query
    현재 원격 검색 쿼리를 취소해요.

    search local(query)
    지정된 쿼리로 로컬 객체를 검색하고 결과를 표시해요.

    has minimum characters
    최소 문자 수를 충족했는지 여부를 나타내요.

    search remote(query, callback)
    지정된 쿼리로 원격 엔드포인트를 검색하고 결과를 표시해요.

    search object(query, object, searchFields)
    지정된 쿼리로 객체를 검색하고 결과를 반환해요.

    is focused
    검색이 현재 포커스되어 있는지 여부를 나타내요.

    is visible
    검색 결과가 보이는지 여부를 나타내요.

    is empty
    검색 결과가 비어 있는지 여부를 나타내요.

    get value
    현재 검색 값을 반환해요.

    get result(value)
    검색된 제목 또는 id와 일치하는 JSON 객체를 반환해요 (위 참고).

    set value(value)
    검색 입력을 값으로 설정해요.

    read cache(query)
    쿼리에 대한 캐시된 결과를 읽어요.

    clear cache(query)
    캐시에서 값을 지우고, 매개변수를 전달하지 않으면 전체 캐시를 지워요.

    write cache(query)
    쿼리에 대한 캐시된 결과를 기록해요.

    add results(html)
    결과에 HTML을 추가하고 표시해요.

    show results(callback)
    결과 컨테이너를 표시해요.

    hide results(callback)
    결과 컨테이너를 숨겨요.

    generate results(response)
    `settings.template`에 지정된 파서를 사용해 결과를 생성해요.

    destroy
    모든 이벤트를 제거해요.

예시 (Examples)

다른 응답 필드 사용하기 (Using Different Response Fields)

Search expects a very specific API response, however you can easily modify the mapping of server response to displayed field using the fields parameter.
      
      $('.ui.search')
        .search({
          apiSettings: {
            url: 'https://api.github.com/search/repositories?q={query}'
          },
          fields: {
            results : 'items',
            title   : 'name',
            url     : 'html_url'
          },
          minCharacters : 3
        })
      ;

검색은 매우 구체적인 API 응답을 기대하지만, fields 매개변수를 사용해 서버 응답을 표시 필드로 매핑하는 것을 쉽게 수정할 수 있어요.

API 설정 사용하기 (Using API Settings)

가능한 XSS 취약점에 대해 보안 섹션을 읽어 보는 것이 좋아요.

Be careful when working with foreign remote API services
      		
      		
      
      
      
      
        
          
          
        
      
      
      $('.ui.search')
        .search({
          type          : 'category',
          minCharacters : 3,
          apiSettings   : {
            onResponse: function(githubResponse) {
              var
                response = {
                  results : {}
                }
              ;
              // GitHub API 응답을 검색에 맞게 변환
              $.each(githubResponse.items, function(index, item) {
                var
                  language   = item.language || 'Unknown',
                  maxResults = 8
                ;
                if(index >= maxResults) {
                  return false;
                }
                // 새 언어 카테고리 생성
                if(response.results[language] === undefined) {
                  response.results[language] = {
                    name    : language,
                    results : []
                  };
                }
                // 결과를 카테고리에 추가
                response.results[language].results.push({
                  title       : item.name,
                  description : item.description,
                  url         : item.html_url
                });
              });
              return response;
            },
            url: 'https://api.github.com/search/repositories?q={query}'
          }
        })
      ;

외부 원격 API 서비스를 다룰 때는 주의해야 해요.

Search (설정)

동작 (Behavior)

  Default / Description

    apiSettings
    
    {
      action: 'search'
    }
    
    
    [API](/behaviors/api.html#/usage) 호출에 대한 설정이에요.

    minCharacters
    1
    결과를 쿼리하기 위한 최소 문자 수예요.

    searchOnFocus
    true
    포커스 시 검색 결과를 표시할지 여부예요 (또한 최소 문자 길이도 일치해야 해요).

    transition
    
      scale
    
    메뉴를 안팎으로 애니메이션할 때 사용하는 이름 있는 트랜지션이에요. Fade와 slide down은 [ui transitions](/modules/transition.html)을 포함하지 않고도 사용할 수 있어요.

    duration
    
      200
    
    애니메이션 이벤트의 지속 시간이에요.

    maxResults
    7
    로컬 및 단순 검색 시 표시할 최대 결과 수이고, 카테고리 검색 시 최대 카테고리 수예요.

    cache
    true
    서버를 다시 쿼리하지 않도록 결과를 로컬에 캐시해요.

    source
    false
    로컬로 검색할 Javascript 객체를 지정해요.

    selectFirstResult
    false
    검색 후 첫 번째 검색 결과를 자동으로 선택할지 여부예요.

    preserveHTML
    true
    결과 집합 값의 가능한 html을 보존할지 여부예요.

    showNoResults
    true
    결과가 없을 때 "결과 없음" 메시지를 표시할지 여부예요. (이 메시지는 아래에 지정된 `template` 객체로 수정할 수 있어요.)

    fullTextSearch
    'exact'
    
      가능한 값
          - 'exact'는 문자열 어딘가에 정확한 검색이 일치하도록 강제해요.

          - 'some'은 exact와 같지만 공백으로 구분된 여러 검색 값을 지원해요. 최소한 한 단어가 일치해야 해요.

          - 'all'은 some과 같지만 모든 단어가 각 레코드의 모든 지정된 searchfield에서 일치해야 해요.

          - true는 퍼지 전체 텍스트 검색을 사용해요.

          - false는 문자열 시작과만 일치해요.
    
    (이 설정은 이전에 `searchFullText`라고 불렸어요.)

    fields
    
      
      fields: {
        categories      : 'results',     // array of categories (category view)
        categoryName    : 'name',        // name of category (category view)
        categoryResults : 'results',     // array of results (category view)
        description     : 'description', // result description
        image           : 'image',       // result image
        alt             : 'alt',         // result alt text for image
        price           : 'price',       // result price
        results         : 'results',     // array of results (standard)
        title           : 'title',       // result title
        url             : 'url',         // result url
        action          : 'action',      // "view more" object name
        actionText      : 'text',        // "view more" text
        actionURL       : 'url'          // "view more" url (if set to false the text will appear as a div)
      }
      
    
    API 또는 `source`로 표시 콘텐츠를 JSON 속성에 매핑한 목록이에요.

    searchFields
    
      
          [
            'id',
            'title',
            'description'
          ]
        
    
    로컬 소스 객체 안에서 검색될 객체 속성을 지정해요.

    hideDelay
    0
    검색 블러 후 결과를 숨기기 전의 지연이에요.

    searchDelay
    200
    입력 변경 시 결과를 쿼리하기 전의 지연이에요.

    easing
    
      easeOutExpo
    
    폴백 Javascipt 애니메이션 사용 시의 이징 방정식이에요. EaseOutExpo는 search에 포함되어 있고, 추가 옵션은 이징 방정식을 포함해야 해요.

    highlightMatches
    false
    검색 결과에서 일치하는 문자열을 강조할지 여부예요.

    ignoreDiacritics
    false
    활성화하면 검색이 기본 발음 구별 부호 글자에 대한 결과도 일치해요. 예를 들어 'a'로 검색하면 'á', 'â', 'å' 등도 일치해요.
        검색어의 발음 구별 부호도 무시해서 'ó'로 검색하면 'ó'뿐 아니라 'o', 'ô', 'õ' 등도 일치해요... IE에서는 사용할 수 없어요.

    ignoreSearchCase
    true
    로컬 검색에서 대소문자 구분을 고려할지 여부예요.

    type
    'standard'
    사용할 템플릿이에요 (settings.templates에 지정).

    displayField
    ''
    표준 결과 템플릿에서 표시할 필드예요.

    automatic
    true
    프롬프트에 이벤트를 자동으로 추가할지 여부예요.

콜백 (Callbacks)

  Context / Description

    onSelect(result, response)
    module
    사용자가 요소를 선택할 때의 콜백이에요. 첫 번째 매개변수는 해당 요소에 대한 필터링된 응답 결과를 포함해요. 기본 동작(검색 결과 닫기와 값 선택)을 방지하려면 false를 반환해야 해요.

    onResultsAdd(html)
    module
    결과에 HTML을 추가하기 위해 요소 템플릿을 처리한 후의 콜백이에요. 기본 동작을 방지하려면 false를 반환해야 해요.

    onSearchQuery(query)
    module
    검색 쿼리에 대한 콜백이에요.

    onResults(response, fromCache)
    module
    서버 응답에 대한 콜백이에요. 결과가 캐시에서 생성되었다면 `fromCache` 매개변수가 `true`예요.

    onResultsOpen
    results element
    결과가 열릴 때의 콜백이에요.

    onResultsClose
    results element
    결과가 닫힐 때의 콜백이에요.

템플릿 (Templates)

이 템플릿들은 검색 결과를 위한 HTML 구조를 생성하는 데 사용돼요.

  검색을 `type: 'customType'`으로 지정하고 `$.fn.search.settings.templates.customType` 아래에 사용자 정의 템플릿을 지정하면 사용자 정의 검색 결과를 만들 수 있어요. `.title`이 `onSelect`에서 결과를 일치시키는 데 사용된다는 점을 기억하세요.

  Functions

    templates
    
      
      $.fn.search.settings.templates : {
        escape: function(string, preserveHTML) {
          // returns escaped string for injected results
        },
        message: function(message, type, header) {
         // returns html for message with given message and type
        },
        category: function(response, fields, preserveHTML) {
         // returns results html for category results
        },
        standard: function(response, fields, preserveHTML) {
         // returns results html for standard results
        }
      }

Module (모듈 설정)

이 설정들은 모든 모듈에 기본 내장되어 있으며, 컴포넌트가 콘텐츠를 DOM 속성에 어떻게 연결하는지와 모듈의 디버깅 설정을 정의해요.

  Default / Description

    name
    Search
    로그 문에서 사용되는 이름이에요.

    namespace
    search
    이벤트 네임스페이스예요. 모듈 해제가 요소에 붙은 다른 이벤트에 영향을 주지 않게 해요.

    regExp
    
      
      regExp: {
        escape     : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
        beginsWith : '(?:\s|^)'
      }
      
    
    일치에 사용되는 정규식이에요.

    selector
    
      
      selector : {
        prompt       : '.prompt',
        searchButton : '.search.button',
        results      : '.results',
        message      : '.results > .message',
        category     : '.category',
        result       : '.result',
        title        : '.title, .name'
      }
      
    
    모듈의 부분을 찾는 데 사용되는 선택자들이에요.

    metadata
    
      
      metadata: {
        cache   : 'cache',
        results : 'results',
        result  : 'result'
      }
      
    
    내부적으로 사용되는 HTML5 메타데이터 속성이에요.

    className
    
      
      className: {
        animating : 'animating',
        active    : 'active',
        category  : 'category',
        empty     : 'empty',
        focus     : 'focus',
        hidden    : 'hidden',
        loading   : 'loading',
        results   : 'results',
        pressed   : 'down'
      }
      
    
    요소 상태를 결정하는 데 사용되는 클래스 이름들이에요.

    silent
    false
    다른 디버그 설정과 관계없이 오류 메시지를 포함한 모든 콘솔 출력을 잠재워요.

    debug
    false
    콘솔에 디버그 출력을 해요.

    performance
    true
    성능 지표와 함께 `console.table` 출력을 표시해요.

    verbose
    false
    디버그 출력에 모든 내부 동작을 포함해요.

    error
    
      
      error : {
        source          : 'Cannot search. No source used, and Semantic API module was not included',
        noResultsHeader : 'No Results',
        noResults       : 'Your search returned no results',
        noTemplate      : 'A valid template name was not specified.',
        oldSearchSyntax : 'searchFullText setting has been renamed fullTextSearch for consistency, please adjust your settings.',
        serverError     : 'There was an issue with querying the server.',
        maxResults      : 'Results must be an array to use maxResults setting',
        method          : 'The method you called is not defined.',
        noNormalize     : '"ignoreDiacritics" setting will be ignored. Browser does not support String().normalize(). You may consider including  as a polyfill.'
      },

신뢰할 수 없는 원격 데이터 다루기 (Taking care of untrusted remote data)

책임 없음 (No responsibility)

  - Fomantic은 remoteData로 작업할 때 XSS를 방지하기 위한 몇 가지 기본 기능을 포함하고 있어요.

  - 어떤 알 수 없는 원격 데이터 소스의 데이터에 대해 사이트가 취약하지 않을 것이라는 보장이나 약속이 없어요.

  - Fomantic-UI는 데이터를 어떻게 처리하고 사용하는지에 대해 책임지지 않아요. fomantic을 사용함으로써 데이터 처리로 인한 문제로 (당신 또는 당신 회사에) 부과된 손해나 비용에 대해 당신이 책임이 있다는 데 동의하게 돼요.

HINT (힌트)
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet 를 살펴보면 더 많은 정보와 주의할 점을 배울 수 있어요.

신뢰할 수 없는 데이터 (Untrusted Data)

어떤 데이터도 절대 신뢰해서는 안 되며, 모든 데이터가 클라이언트로 전달되기 전에 서버에서 처리되어 살균(sanitize)되도록 해야 해요.

그러나 검색 모듈의 데이터 저장소로 기존 외부 API 서비스를 사용하고 싶을 수도 있어요. 이 경우 preserveHTML 옵션을 false로 설정하는 것이 권장돼요. 그러면 프론트엔드가 제공하는 모든 데이터가 &, <, >, ", ', \` 같은 가장 위험한 문자에 대해 HTML 엔티티로 인코딩되거나, 항목을 선택할 때 모든 html 데이터가 완전히 제거돼요.

$('.ui.search') .search({ preserveHTML : false, apiSettings: { url: 'https://api.github.com/search/repositories?q={query}' }, fields: { results : 'items', title : 'name', url : 'html_url' }, minCharacters : 3 });

악성 API 예시 (Evil API Example)

다음 검색 필드들은 코드를 주입하려는 악성 API 백엔드에 바인딩되어 있어요.

	- 검색 필드에 최소 2문자를 입력하면 API 호출이 발생해요.

	- 첫 번째 예시의 기본(따라서 생략된) 설정 preserveHTML:true는 즉시 alert 메시지를 발생시켜요.

	- 또한 검색 항목의 추가 클릭 이벤트 핸들러(빨간색 표시)에 숨겨진 코드를 주입해요. 원하는 검색 결과를 선택할 때처럼 클릭해 보세요.

	- 악성 예시 코드는 한 번 실행된 후 DOM에서 스스로 제거돼요.

취약한 버전 (Vulnerable Version)

$('.ui.search.evilexample')
          .search({
        	apiSettings: {
        	  url: '/evilapi.json'
        	},
        	fields: {
        	  title   : 'name'
        	},
        	minCharacters : 2
          });

살균된 버전 (Sanitized Version)

$('.ui.search.evilexample_sanitized')
          .search({
        	preserveHTML : false,
        	apiSettings: {
        	  url: '/evilapi.json'
        	},
        	fields: {
        	  title   : 'name'
        	},
        	minCharacters : 2
          });

더 알아보기 (Learn more)