首页 > 解决方案 > 有什么方法可以为多个打开多个 get xmlhttprequests

  • 点击它们时的标签?
  • 问题描述

    在这里,我试图通过更改 newsApi 中的 source="countrycode" 来获取 10 个国家的新闻标题的 xmlhttprequest。我为 10 个国家/地区声明<li>了 10 个标签,并为每个标签提供了一个 onclick 函数,该函数调用一个 js 函数,在该函数中我将国家代码附加到 api。但它不起作用。我检查了 API 工作正常。如果我提供任何国家代码(例如,巴西的“br”)工作正常,我还检查了对 api 的单一调用。但它不能在函数内部工作。我究竟做错了什么 ?

    [我在代码中更改了我的 API 密钥以解决隐私问题]

    function requestXml(str) {
      let source = str.value;
      // console.log(str);
      // console.log(source);
      // e.preventDefault();
      let apiKey = 'something';
    
      // Grab the news container
      let newsAccordion = document.getElementById('newsAccordion');
    
      // Create an ajax get request
      const xhr = new XMLHttpRequest();
      xhr.open('GET', `http://newsapi.org/v2/top-headlines?country=${source}&apiKey=${apiKey}`, true);
    
      // What to do when response is ready
      xhr.onload = function() {
        if (this.status === 200) {
          let json = JSON.parse(this.responseText);
          let articles = json.articles;
          console.log(articles);
          let newsHtml = "";
          articles.forEach(function(element, index) {
            // console.log(element, index)
            let news = `<div class="card">
              <div class="card-header" id="heading${index}">
                <h2 class="mb-0">
                  <button class="btn btn-link collapsed" type="button" 
                  data-toggle="collapse" data-target="#collapse${index}"
                  aria-expanded="false" aria-controls="collapse${index}">
                    <b>Breaking News ${index + 1}:</b> ${element["title"]}
                  </button>
                </h2>
              </div>
              <div id="collapse${index}" class="collapse" aria-labelledby="heading${index}" 
              data-parent="#newsAccordion">
                <div class="card-body"> ${element["content"]}. 
                  <a href="${element['url']}" target="_blank" >Read more here</a>  
                </div>
              </div>
            </div>`;
            newsHtml += news;
          });
          newsAccordion.innerHTML = newsHtml;
        } else {
          console.log("Some error occured")
        }
      }
    
      xhr.send();
    
    }
    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
          <ul class="nav nav-sidebar">
            <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
            <hr>
            <li id="br" value="br" onclick="requestXml(this)"><a href="">Brazil</a></li>
            <li id="ca" value="ca" onclick="requestXml(this)"><a href="">Canada</a></li>
            <li id="cn" value="cn" onclick="requestXml(this)"><a href="">China</a></li>
            <li id="fr" value="fr" onclick="requestXml(this)"><a href="">France</a></li>
            <li id="de" value="de" onclick="requestXml(this)"><a href="">Germany</a></li>
            <li id="in" value="in" onclick="requestXml(this)"><a href="">India</a></li>
            <li id="it" value="it" onclick="requestXml(this)"><a href="">Italy</a></li>
            <li id="jp" value="jp" onclick="requestXml(this)"><a href="">Japan</a></li>
            <li id="gb" value="gb" onclick="requestXml(this)"><a href="">United Kingdom</a></li>
            <li id="us" value="us" onclick="requestXml(this)"><a href="">United States</a></li>
          </ul>
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
          <h1 class="page-header">Dashboard</h1>
          <div class="container my-3">
            <h3>Top News <span class="badge badge-secondary">by Indian shatabdi News</span></h3>
            <hr>
            <div class="accordion" id="newsAccordion"></div>
          </div>
    
        </div>
      </div>
    </div>

    标签: javascripthtmlajaxxmlhttprequest

    解决方案


    几个问题

    • LI 不仅有value表单字段

    • 您点击链接,而不是 LI

    • 如果您只想点击某些内容,则无需链接

    • 您正在使用 http 而不是 https

    注意下面的代码在没有有效 api 密钥的情况下无法运行,但正如您所见,它正在调用它

    function requestXml(source) {
      let apiKey = 'some key';
    
      // Grab the news container
      let newsAccordion = document.getElementById('newsAccordion');
    
      // Create an ajax get request
      const xhr = new XMLHttpRequest();
      xhr.open('GET', `https://newsapi.org/v2/top-headlines?country=${source}&apiKey=${apiKey}`, true);
    
      // What to do when response is ready
      xhr.onload = function() {
        if (this.status === 200) {
          let json = JSON.parse(this.responseText);
          let articles = json.articles;
          console.log(articles);
          let newsHtml = "";
          articles.forEach(function(element, index) {
            // console.log(element, index)
            let news = `<div class="card">
              <div class="card-header" id="heading${index}">
                <h2 class="mb-0">
                  <button class="btn btn-link collapsed" type="button" 
                  data-toggle="collapse" data-target="#collapse${index}"
                  aria-expanded="false" aria-controls="collapse${index}">
                    <b>Breaking News ${index + 1}:</b> ${element["title"]}
                  </button>
                </h2>
              </div>
              <div id="collapse${index}" class="collapse" aria-labelledby="heading${index}" 
              data-parent="#newsAccordion">
                <div class="card-body"> ${element["content"]}. 
                  <a href="${element['url']}" target="_blank" >Read more here</a>  
                </div>
              </div>
            </div>`;
            newsHtml += news;
          });
          newsAccordion.innerHTML = newsHtml;
        } else {
          console.log("Some error occured")
        }
      }
    
      xhr.send();
    
    }
    
    document.getElementById("list").addEventListener("click",function(e) {
      const tgt = e.target;
      const cc = tgt.dataset.cc;
      requestXml(cc)
    })
    #list li { cursor:pointer; }
    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
          <ul class="nav nav-sidebar" id="list">
            <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
            <hr>
            <li id="br" data-cc="br">Brazil</li>
            <li id="ca" data-cc="ca">Canada</li>
            <li id="cn" data-cc="cn">China</li>
            <li id="fr" data-cc="fr">France</li>
            <li id="de" data-cc="de">Germany</li>
            <li id="in" data-cc="in">India</li>
            <li id="it" data-cc="it">Italy</li>
            <li id="jp" data-cc="jp">Japan</li>
            <li id="gb" data-cc="gb">United Kingdom</li>
            <li id="us" data-cc="us">United States</li>
          </ul>
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
          <h1 class="page-header">Dashboard</h1>
          <div class="container my-3">
            <h3>Top News <span class="badge badge-secondary">by Indian shatabdi News</span></h3>
            <hr>
            <div class="accordion" id="newsAccordion"></div>
          </div>
    
        </div>
      </div>
    </div>

    运行代码以测试解析逻辑时的示例

    注意字符串中有 \r\n 我必须双重转义

    function show(jsonStr) {
      let obj = JSON.parse(jsonStr);
      let articles = obj.articles;
    //  console.log(articles);
      let newsHtml = "";
      articles.forEach(function(element, index) {
        // console.log(element, index)
        let news = `<div class="card">
              <div class="card-header" id="heading${index}">
                <h2 class="mb-0">
                  <button class="btn btn-link collapsed" type="button" 
                  data-toggle="collapse" data-target="#collapse${index}"
                  aria-expanded="false" aria-controls="collapse${index}">
                    <b>Breaking News ${index + 1}:</b> ${element["title"]}
                  </button>
                </h2>
              </div>
              <div id="collapse${index}" class="collapse" aria-labelledby="heading${index}" 
              data-parent="#newsAccordion">
                <div class="card-body"> ${element["content"]}. 
                  <a href="${element['url']}" target="_blank" >Read more here</a>  
                </div>
              </div>
            </div>`;
        newsHtml += news;
      });
      newsAccordion.innerHTML = newsHtml;
    
    }
    const json = `{
    "status": "ok",
    "totalResults": 34,
    "articles": [
    {
    "source": {
    "id": null,
    "name": "Le 10 Sport"
    },
    "author": "G.d.S.S.",
    "title": "Mercato - PSG : Le prochain club de Tuchel devrait être… - Le 10 Sport",
    "description": "En fin de contrat en juin prochain avec le PSG, Thomas Tuchel ne devrait pas être prolongé par le club de la capitale. Et Manchester United semble bien parti pour relancer le technicien allemand cet…",
    "url": "https://le10sport.com/football/mercato/mercato-psg-le-prochain-club-de-tuchel-devrait-etre-530383",
    "urlToImage": "https://le10static.com/img/master/0000/0018/180166.jpeg",
    "publishedAt": "2020-12-21T01:00:00Z",
    "content": "Publié le 21 décembre 2020 à 2h00 par G.d.S.S. En fin de contrat en juin prochain avec le PSG, Thomas Tuchel ne devrait pas être prolongé par le club de la capitale. Et Manchester United semble bien … [+993 chars]"
    },
    {
    "source": {
    "id": null,
    "name": "Foot Mercato"
    },
    "author": "Alexis Pereira",
    "title": "Christophe Galtier rend hommage au jardinier disparu au Moustoir - Foot Mercato",
    "description": "",
    "url": "https://www.footmercato.net/a4286436182457181763-christophe-galtier-rend-hommage-au-jardinier-disparu-au-moustoir",
    "urlToImage": "https://assets-fr.imgfoot.com/media/cache/1200x675/galtier-losc-2020.jpg",
    "publishedAt": "2020-12-21T00:25:38Z",
    "content": "La suite après cette publicité\\r\\nAu sortir du revers du FC Lorient face au Stade Rennais ce dimanche après-midi (0-3, 16e journée de Ligue 1), un terrible accident s'est produit sur la pelouse du Stad… [+238 chars]"
    }
    ]
    }`
    
    
    show(json)
    #list li {
      cursor: pointer;
    }
    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
          <ul class="nav nav-sidebar" id="list">
            <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
            <hr>
            <li id="br" data-cc="br">Brazil</li>
            <li id="ca" data-cc="ca">Canada</li>
            <li id="cn" data-cc="cn">China</li>
            <li id="fr" data-cc="fr">France</li>
            <li id="de" data-cc="de">Germany</li>
            <li id="in" data-cc="in">India</li>
            <li id="it" data-cc="it">Italy</li>
            <li id="jp" data-cc="jp">Japan</li>
            <li id="gb" data-cc="gb">United Kingdom</li>
            <li id="us" data-cc="us">United States</li>
          </ul>
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
          <h1 class="page-header">Dashboard</h1>
          <div class="container my-3">
            <h3>Top News <span class="badge badge-secondary">by Indian shatabdi News</span></h3>
            <hr>
            <div class="accordion" id="newsAccordion"></div>
          </div>
    
        </div>
      </div>
    </div>


    推荐阅读