HTTP GET запит у JavaScript?


807

Мені потрібно зробити HTTP GET- запит у JavaScript. Який найкращий спосіб зробити це?

Мені потрібно це зробити у віджеті даш-коду Mac OS X.


10
Зауважте, що це поширюється на ту саму політику щодо походження. en.wikipedia.org/wiki/Same_origin_policy
ripper234

Відповіді:


1206

Браузери (та Dashcode) надають об'єкт XMLHttpRequest, який можна використовувати для створення HTTP-запитів із JavaScript:

function httpGet(theUrl)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
    xmlHttp.send( null );
    return xmlHttp.responseText;
}

Однак синхронні запити не перешкоджають і генеруватимуть попередження:

Примітка. Починаючи з Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), синхронні запити на основній нитці були вичерпані через негативні наслідки для роботи користувача.

Вам слід зробити асинхронний запит та обробити відповідь всередині обробника події.

function httpGetAsync(theUrl, callback)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = function() { 
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            callback(xmlHttp.responseText);
    }
    xmlHttp.open("GET", theUrl, true); // true for asynchronous 
    xmlHttp.send(null);
}

2
Ну і, звичайно, вбудований Javascript, або як будь-яка бібліотека Javascript могла запропонувати для нього зручний метод? Різниця полягає в тому, що методи зручності пропонують, ну, зручність і чіткіший, простіший синтаксис.
Пістос

37
Чому префікс XML?
АлікЕльзін-кілака

9
Префікс XML, оскільки він використовує X від AJAX ~ Асинхронний JavaScript та XML . Крім того, хороший підсумок " API, який має, і прив'язка ECMAScript " пов'язаний з тим, що JavaScript може бути в багатьох речах, окрім браузерів, що підтримують HTTP (наприклад, як Adobe Reader ...). Вказані вуха.
буде

7
@ AlikElzin-kilaka Насправді всі відповіді, зазначені вище, є поза знаком (інфакт пов'язаних документів W3 пояснює "кожен компонент цього імені потенційно оманливий"). Правильна відповідь? його просто погано імені stackoverflow.com/questions/12067185 / ...
Ешлі Coolman

2
Вибірки API пропонує кращий спосіб зробити це, і може бути polyfilled при необхідності (див @ PeterGibson в відповідь нижче ).
Dominus.Vobiscum

190

У jQuery :

$.get(
    "somepage.php",
    {paramOne : 1, paramX : 'abc'},
    function(data) {
       alert('page content: ' + data);
    }
);

4
зауважте, що це не працює в IE 10 при спробі отримати доступ до URL-адреси в іншому домені, ніж домен сторінки
BornToCode

5
@BornToCode вам слід далі дослідити і, можливо, відкрити помилку на трекері проблем jQuery у такому випадку
ashes999

91
Я знаю, що деякі хочуть писати чистий Javascript. Я це розумію. У мене немає проблем з тим, що люди роблять це у своїх проектах. Мій текст "В jQuery:" повинен бути викладений як "Я знаю, що ви запитали, як це зробити в Javascript, але дозвольте мені показати вам, як би ви це зробили з jQuery, щоб у вас з'явилася цікавість, побачивши, яку стислість синтаксису і ясність, яку ви можете насолоджуватися, користуючись цією бібліотекою, яка також дозволить вам отримати численні інші переваги та засоби ".
Пістос

34
Зауважте також, що пізніше початковий плакат сказав: "Дякую за всі відповіді! Я пішов з jQuery на основі деяких речей, які я читав на їхньому сайті".
Пістос

153

Вище чудових порад, але не дуже багаторазових і занадто часто наповнених дурницями DOM та іншим пухом, який приховує простий код.

Ось клас Javascript, який ми створили, який може бути багаторазовим та простим у використанні. Наразі це лише метод GET, але це працює для нас. Додавання POST не повинно оподатковувати навички нікого.

var HttpClient = function() {
    this.get = function(aUrl, aCallback) {
        var anHttpRequest = new XMLHttpRequest();
        anHttpRequest.onreadystatechange = function() { 
            if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
                aCallback(anHttpRequest.responseText);
        }

        anHttpRequest.open( "GET", aUrl, true );            
        anHttpRequest.send( null );
    }
}

Використовувати його так само просто, як:

var client = new HttpClient();
client.get('http://some/thing?with=arguments', function(response) {
    // do something with response
});

Помилка UnCaughtReference, HttpClient не визначена. Я отримую цей перший рядок це сам.
сашиканта

Як ви називаєте це з html onClick?
Гоблінс

Зробіть іншу функцію, де він містить клієнт var ... та просто запустіть functionName (); повернути помилкове; в onClick
mail929

1
ReferenceError: XMLHttpRequest is not defined
Bugs Buggy

122

Новий window.fetchAPI - це чистіша заміна, XMLHttpRequestяка використовує обіцянки ES6. Там гарне пояснення тут , але вона зводиться до (зі статті):

fetch(url).then(function(response) {
  return response.json();
}).then(function(data) {
  console.log(data);
}).catch(function() {
  console.log("Booo");
});

Підтримка браузера тепер хороша в останніх випусках (працює в Chrome, Firefox, Edge (v14), Safari (v10.1), Opera, Safari iOS (v10.3), браузері Android та Chrome для Android), проте IE буде швидше за все, не отримає офіційної підтримки. У GitHub є поліфіл, який рекомендується підтримувати старими браузерами, які все ще широко використовуються (esp версії Safari до березня 2017 року та мобільні браузери того ж періоду).

Я здогадуюсь, чи це зручніше, ніж jQuery чи XMLHttpRequest чи ні, залежить від характеру проекту.

Ось посилання на специфікацію https://fetch.spec.whatwg.org/

Редагувати :

Використовуючи ES7 async / wait, це стає просто (виходячи з цього суті ):

async function fetchAsync (url) {
  let response = await fetch(url);
  let data = await response.json();
  return data;
}

9
Я можу заощадити когось деякий час, зазначивши, що ви можете це зробити, щоб у запит включити облікові дані:fetch(url, { credentials:"include" })
Енселік

@ bugmenot123 window.fetchне поставляється з аналізатором XML, але ви можете самостійно проаналізувати відповідь, якщо обробите її як текст (а не json, як у наведеному вище прикладі). Дивіться приклад stackoverflow.com/a/37702056/66349
Пітер Гібсон

94

Версія без зворотного дзвінка

var i = document.createElement("img");
i.src = "/your/GET/url?params=here";

2
Відмінно! Мені знадобився сценарій Greasemonkey, щоб підтримувати сеанс в живих, і цей фрагмент ідеальний. Просто загорнув це у setIntervalдзвінок.
Carcamano

9
як я отримую результат?
user4421975

@ user4421975 Ви не отримуєте - щоб отримати доступ до відповіді на запит, замість цього потрібно використовувати вищезгаданий XMLHttpRequest.
Якуб Пастушук

74

Ось код, щоб зробити це безпосередньо за допомогою JavaScript. Але, як згадувалося раніше, вам буде набагато краще з бібліотекою JavaScript. Мій улюблений - jQuery.

У нижченаведеному випадку викликається сторінка ASPX (яка обслуговується як REST-послуга бідної людини), щоб повернути об’єкт JavaScript JSON.

var xmlHttp = null;

function GetCustomerInfo()
{
    var CustomerNumber = document.getElementById( "TextBoxCustomerNumber" ).value;
    var Url = "GetCustomerInfoAsJson.aspx?number=" + CustomerNumber;

    xmlHttp = new XMLHttpRequest(); 
    xmlHttp.onreadystatechange = ProcessRequest;
    xmlHttp.open( "GET", Url, true );
    xmlHttp.send( null );
}

function ProcessRequest() 
{
    if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) 
    {
        if ( xmlHttp.responseText == "Not found" ) 
        {
            document.getElementById( "TextBoxCustomerName"    ).value = "Not found";
            document.getElementById( "TextBoxCustomerAddress" ).value = "";
        }
        else
        {
            var info = eval ( "(" + xmlHttp.responseText + ")" );

            // No parsing necessary with JSON!        
            document.getElementById( "TextBoxCustomerName"    ).value = info.jsonData[ 0 ].cmname;
            document.getElementById( "TextBoxCustomerAddress" ).value = info.jsonData[ 0 ].cmaddr1;
        }                    
    }
}

33
Оскільки ця відповідь є одним з найкращих результатів для googling "http запиту javascript", варто згадати, що запускати eval на подібні дані відповіді вважається поганою практикою
Kloar

9
@Kloar хороший момент, але було б ще краще навести причину, чому це погано, напевне, це безпека. Пояснення, чому практика погана - це найкращий спосіб змусити людей переключити свої звички.
Бальміпур

43

Сучасна версія копіювання-вставки (використовуючи функцію вилучення та стрілки ) :

//Option with catch
fetch( textURL )
   .then(async r=> console.log(await r.text()))
   .catch(e=>console.error('Boo...' + e));

//No fear...
(async () =>
    console.log(
            (await (await fetch( jsonURL )).json())
            )
)();

Класична версія копію-вставлення:

let request = new XMLHttpRequest();
request.onreadystatechange = function () {
    if (this.readyState === 4) {
        if (this.status === 200) {
            document.body.className = 'ok';
            console.log(this.responseText);
        } else if (this.response == null && this.status === 0) {
            document.body.className = 'error offline';
            console.log("The computer appears to be offline.");
        } else {
            document.body.className = 'error';
        }
    }
};
request.open("GET", url, true);
request.send(null);


19

IE буде кешувати URL-адреси, щоб зробити швидше завантаження, але якщо ви, скажімо, опитуєте сервер з інтервалом, намагаючись отримати нову інформацію, IE буде кешувати цю URL-адресу і, ймовірно, поверне той самий набір даних, який ви завжди мали.

Незалежно від того, як ви закінчите робити свій GET-запит - ванільний JavaScript, прототип, jQuery тощо - переконайтеся, що ви встановили механізм для боротьби з кешуванням. Для боротьби з цим додайте унікальний маркер до кінця URL-адреси, про яку ви збираєтесь звертатися. Це можна зробити:

var sURL = '/your/url.html?' + (new Date()).getTime();

Це додасть унікальну часову позначку до кінця URL-адреси і запобіжить жодному кешуванню.


12

Прототип робить його мертвим простим

new Ajax.Request( '/myurl', {
  method:  'get',
  parameters:  { 'param1': 'value1'},
  onSuccess:  function(response){
    alert(response.responseText);
  },
  onFailure:  function(){
    alert('ERROR');
  }
});

2
Проблема полягає в тому, що Mac OS X не поставляється з попередньо встановленим прототипом. Оскільки віджет потрібно запускати на будь-якому комп’ютері, включаючи прототип (або jQuery) у кожному віджеті, це не найкраще рішення.
kiamlaluno

@kiamlaluno використовуйте прототип cdn з cloudflare
Володимир Стажилов

10

Одне рішення з підтримкою старих браузерів:

function httpRequest() {
    var ajax = null,
        response = null,
        self = this;

    this.method = null;
    this.url = null;
    this.async = true;
    this.data = null;

    this.send = function() {
        ajax.open(this.method, this.url, this.asnyc);
        ajax.send(this.data);
    };

    if(window.XMLHttpRequest) {
        ajax = new XMLHttpRequest();
    }
    else if(window.ActiveXObject) {
        try {
            ajax = new ActiveXObject("Msxml2.XMLHTTP.6.0");
        }
        catch(e) {
            try {
                ajax = new ActiveXObject("Msxml2.XMLHTTP.3.0");
            }
            catch(error) {
                self.fail("not supported");
            }
        }
    }

    if(ajax == null) {
        return false;
    }

    ajax.onreadystatechange = function() {
        if(this.readyState == 4) {
            if(this.status == 200) {
                self.success(this.responseText);
            }
            else {
                self.fail(this.status + " - " + this.statusText);
            }
        }
    };
}

Можливо, дещо завищене, але з цим кодом ви обов'язково перебуваєте в безпеці.

Використання:

//create request with its porperties
var request = new httpRequest();
request.method = "GET";
request.url = "https://example.com/api?parameter=value";

//create callback for success containing the response
request.success = function(response) {
    console.log(response);
};

//and a fail callback containing the error
request.fail = function(error) {
    console.log(error);
};

//and finally send it away
request.send();

2
Чи можете люди прокоментувати будь-які коментарі щодо того, що я зробив неправильно? Не дуже корисно таким чином!
політP0tat0

Найкраща відповідь, на мою думку, якщо кодувати в ES5 за допомогою простого javascript.
CoderX

8

Я не знайомий з віджетами Dashcode Mac OS, але якщо вони дозволяють вам використовувати бібліотеки JavaScript та підтримувати XMLHttpRequests , я б використовував jQuery і робив щось подібне:

var page_content;
$.get( "somepage.php", function(data){
    page_content = data;
});

5

У файлі Info.plist вашого віджета не забудьте встановити свій AllowNetworkAccessключ на true.


5

Найкращий спосіб - використовувати AJAX (простий підручник можна знайти на цій сторінці Tizag ). Причина полягає в тому, що будь-яка інша методика, яку ви можете використовувати, вимагає більше коду, це не гарантовано, щоб працювати між кросс-браузером без переробки та вимагає використання більшої кількості клієнтської пам'яті, відкриваючи приховані сторінки всередині кадрів, передаючи URL-адреси, аналізуючи їх дані та закриваючи їх. AJAX - це шлях у цій ситуації. Що за мої два роки роботи в JavaScript важкий розвиток.


5

Для тих, хто використовує AngularJs , це $http.get:

$http.get('/someUrl').
  success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });

5

Ви можете отримати запит HTTP GET двома способами:

  1. Цей підхід базується на форматі XML. Ви повинні передати URL-адресу запиту.

    xmlhttp.open("GET","URL",true);
    xmlhttp.send();
  2. Цей заснований на jQuery. Ви повинні вказати URL-адресу та ім’я функції, яке ви хочете зателефонувати.

    $("btn").click(function() {
      $.ajax({url: "demo_test.txt", success: function_name(result) {
        $("#innerdiv").html(result);
      }});
    }); 

5

Для цього API Fetch - це рекомендований підхід, використовуючи обіцянки JavaScript. XMLHttpRequest (XHR), об'єкт IFrame або динамічні теги є більш старими (і незграбними) підходами.

<script type=“text/javascript”> 
    // Create request object 
    var request = new Request('https://example.com/api/...', 
         { method: 'POST', 
           body: {'name': 'Klaus'}, 
           headers: new Headers({ 'Content-Type': 'application/json' }) 
         });
    // Now use it! 

   fetch(request) 
   .then(resp => { 
         // handle response }) 
   .catch(err => { 
         // handle errors 
    }); </script>

Ось чудова демонстраційна демонстрація та MDN-документи


4
function get(path) {
    var form = document.createElement("form");
    form.setAttribute("method", "get");
    form.setAttribute("action", path);
    document.body.appendChild(form);
    form.submit();
}


get('/my/url/')

Те ж саме можна зробити і після надсилання запиту.
Перегляньте цей посилання на посилання на JavaScript, як надіслати форму


4

Простий запит на асинхронізацію:

function get(url, callback) {
  var getRequest = new XMLHttpRequest();

  getRequest.open("get", url, true);

  getRequest.addEventListener("readystatechange", function() {
    if (getRequest.readyState === 4 && getRequest.status === 200) {
      callback(getRequest.responseText);
    }
  });

  getRequest.send();
}


2
// Create a request variable and assign a new XMLHttpRequest object to it.
var request = new XMLHttpRequest()

// Open a new connection, using the GET request on the URL endpoint
request.open('GET', 'restUrl', true)

request.onload = function () {
  // Begin accessing JSON data here
}

// Send request
request.send()

1

Якщо ви хочете використовувати код для віджета панелі інструментів, і ви не хочете включати бібліотеку JavaScript у кожен створений віджет, тоді ви можете використовувати об’єкт XMLHttpRequest, який Safari спочатку підтримує.

Як повідомляє Ендрю Хеджес, віджет за замовчуванням не має доступу до мережі; вам потрібно змінити це налаштування в info.plist, пов’язаному із віджетом.


1

Щоб оновити найкращу відповідь Джоанн з обіцянкою, це мій код:

let httpRequestAsync = (method, url) => {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open(method, url);
        xhr.onload = function () {
            if (xhr.status == 200) {
                resolve(xhr.responseText);
            }
            else {
                reject(new Error(xhr.responseText));
            }
        };
        xhr.send();
    });
}

1

Сучасний, чистий і найкоротший

fetch('https://www.randomtext.me/api/lorem')


0

Ви можете зробити це і з чистим JS:

// Create the XHR object.
function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}

// Make the actual CORS request.
function makeCorsRequest() {
 // This is a sample server that supports CORS.
 var url = 'http://html5rocks-cors.s3-website-us-east-1.amazonaws.com/index.html';

var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}

// Response handlers.
xhr.onload = function() {
var text = xhr.responseText;
alert('Response from CORS request to ' + url + ': ' + text);
};

xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};

xhr.send();
}

Дивіться: детальніше: html5rocks підручник


0
<button type="button" onclick="loadXMLDoc()"> GET CONTENT</button>

 <script>
        function loadXMLDoc() {
            var xmlhttp = new XMLHttpRequest();
            var url = "<Enter URL>";``
            xmlhttp.onload = function () {
                if (xmlhttp.readyState == 4 && xmlhttp.status == "200") {
                    document.getElementById("demo").innerHTML = this.responseText;
                }
            }
            xmlhttp.open("GET", url, true);
            xmlhttp.send();
        }
    </script>

-1

Ось альтернатива xml-файлам, щоб завантажити файли як об’єкт і отримати доступ до властивостей як об’єкта дуже швидко.

  • Увага, щоб javascript міг його та правильно інтерпретувати вміст, потрібно зберегти ваші файли у тому ж форматі, що і ваша HTML-сторінка. Якщо ви використовуєте UTF 8, збережіть свої файли в UTF8 тощо.

XML працює як дерево нормально? замість того, щоб писати

     <property> value <property> 

написати такий простий файл, як цей:

      Property1: value
      Property2: value
      etc.

Збережіть файл. Тепер зателефонуйте до функції….

    var objectfile = {};

function getfilecontent(url){
    var cli = new XMLHttpRequest();

    cli.onload = function(){
         if((this.status == 200 || this.status == 0) && this.responseText != null) {
        var r = this.responseText;
        var b=(r.indexOf('\n')?'\n':r.indexOf('\r')?'\r':'');
        if(b.length){
        if(b=='\n'){var j=r.toString().replace(/\r/gi,'');}else{var j=r.toString().replace(/\n/gi,'');}
        r=j.split(b);
        r=r.filter(function(val){if( val == '' || val == NaN || val == undefined || val == null ){return false;}return true;});
        r = r.map(f => f.trim());
        }
        if(r.length > 0){
            for(var i=0; i<r.length; i++){
                var m = r[i].split(':');
                if(m.length>1){
                        var mname = m[0];
                        var n = m.shift();
                        var ivalue = m.join(':');
                        objectfile[mname]=ivalue;
                }
            }
        }
        }
    }
cli.open("GET", url);
cli.send();
}

тепер ви можете отримати свої цінності ефективно.

getfilecontent('mesite.com/mefile.txt');

window.onload = function(){

if(objectfile !== null){
alert (objectfile.property1.value);
}
}

Це просто маленький подарунок, щоб привітати групу. Дякуємо, що подобається :)

Якщо ви хочете перевірити функцію на вашому ПК локально, перезавантажте веб-переглядач за допомогою наступної команди (підтримується всіма браузерами, крім сафарі):

yournavigator.exe '' --allow-file-access-from-files
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.