簡體   English   中英

使用全局 XMLHttpRequest 是不好的做法嗎?

[英]Is it bad practice to use a global XMLHttpRequest?

我正在研究此頁面中的示例,試圖學習一些 javascript: https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started

我有一個小的 web 服務器和一個我制作的狀態頁面,我想用它來檢查 web 服務器的狀態。 我構建它的方式是我想檢查 web 服務器onLoad的狀態,而不是使用按鈕。

HTML
Just using:     <body onload=pingSite();> to try to automatically run the check when the page loads.

Javascript
  <script>
            let xhr = new XMLHttpRequest(); <--- The question and the problem.
            function pingSite() {
                var xhr = new XMLHttpRequest();
                response = 'xyz';
                //If an XMLHTTP instance cannot be created
                if(!xhr)
                {
                    response = 'Internal error: Cannot create XMLHTTP instance.'
                    return response;
                }
                xhr.onreadystatechange = HandlePing;
                xhr.open('GET', 'mysite.com');
                xhr.send();
                
                return response;
            }

            function HandlePing() {
                    //If the request has finished
                if(xhr.readyState === XMLHttpRequest.DONE)
                {
                    try {
                        //If the status is 200 (IE we have recieved a response back indicating the server is up.)
                        if(xhr.status === 200)
                        {
                            alert("Server is up");
                        }
                        else
                        {
                            alert("There was a problem with the request");
                        }
                    //If the server is down. 
                    } catch (error) {
                        alert(`Caught Exception: ${error.description}`);
                    }
                }
                else
                {
                    response = 'Pinging...';
                }
            }

    </script>

我遇到的問題有兩個: 1.) 我可以讓它工作的唯一方法是在我的腳本中在兩個函數上方創建一個全局變量,以便讓調用工作。 我有一種直覺,這是非常危險和不好的做法。 是嗎,如果是的話,解決這個問題的更好方法是什么?

2.)我設置它的方式似乎有效,但它沒有返回任何表明它完全有效的跡象。 沒有警報。 沒有回應。 控制台是空的。 我錯過了什么嗎? 盡管我正在加載它,但我是否需要 HTML 中的事件處理程序?

您可以通過創建將 xhr 作為參數傳遞的匿名內聯 function 來避開全局變量:

xhr.onreadystatechange = () => HandlePing(xhr);

或使用綁定

// same as arrow function above but harder to read
xhr.onreadystatechange = HandlePing.bind(null, xhr);

或者,假設您在其他任何地方都不需要它,您可以將HandlePing function 聲明移動到pingSite function 中:

function pingSite() {
  function handlePing() {
    if(xhr.readyState === XMLHttpRequest.DONE)
    // ...
  }

  const xhr = new XMLHttpRequest();

  // ...other stuff...

  const xhr.onreadystatechange = HandlePing;
  // ...
}

一些額外的想法:

  1. 您應該使用fetch而不是 XMLHttpRequest。

  2. 您應該使用addEventListener而不是將onload屬性附加到正文。

  3. fetch 使用Promises ,這使得管理異步行為更容易。

骨架實現可能如下所示:

window.addEventListener('load', handleLoadEvent);

function handleLoadEvent(e) {
   fetch('http://example.com')
      .then( response => {
        // do stuff with the response
      })
      .catch( error => {
        // deal with errors
      })
}

如果你不想用handleLoadEvent function 污染全局命名空間,你可以把它全部包裝在一個IIFE中:

(function () {
  window.addEventListener('load', handleLoadEvent);

  function handleLoadEvent(e) {
     fetch('http://example.com')
        .then( response => {
          // do stuff with the response
        })
        .catch( error => {
          // deal with errors
        })
  }
})()

或者,如果您更喜歡 async/await,您可以這樣編寫handleLoadEvent function:

async function handleLoadEvent(e) {
  try {
    const response = await fetch('http://example.com');
    // do stuff with response
  }
  catch (e) {
    // deal with error
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM