Muszę wykonać żądanie HTTP GET w JavaScript. Jak najlepiej to zrobić?
Muszę to zrobić w widżecie kodu kreskowego Mac OS X.
Muszę wykonać żądanie HTTP GET w JavaScript. Jak najlepiej to zrobić?
Muszę to zrobić w widżecie kodu kreskowego Mac OS X.
Odpowiedzi:
Przeglądarki (i Dashcode) udostępniają obiekt XMLHttpRequest, którego można używać do wysyłania żądań HTTP z JavaScript:
function httpGet(theUrl)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
xmlHttp.send( null );
return xmlHttp.responseText;
}
Jednak żądania synchroniczne są odradzane i generują ostrzeżenie w następujący sposób:
Uwaga: Począwszy od Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), żądania synchroniczne w głównym wątku zostały wycofane z powodu negatywnego wpływu na wrażenia użytkownika.
Należy wykonać żądanie asynchroniczne i obsłużyć odpowiedź w module obsługi zdarzeń.
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);
}
W jQuery :
$.get(
"somepage.php",
{paramOne : 1, paramX : 'abc'},
function(data) {
alert('page content: ' + data);
}
);
Wiele świetnych porad powyżej, ale niezbyt wielokrotnego użytku i zbyt często wypełnionych nonsensami DOM i innymi puchami, które ukrywają łatwy kod.
Oto utworzona przez nas klasa JavaScript, która jest wielokrotnego użytku i łatwa w użyciu. Obecnie ma tylko metodę GET, ale to działa dla nas. Dodanie POST nie powinno obciążać niczyich umiejętności.
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 );
}
}
Korzystanie z niego jest tak proste, jak:
var client = new HttpClient();
client.get('http://some/thing?with=arguments', function(response) {
// do something with response
});
ReferenceError: XMLHttpRequest is not defined
Nowe window.fetch
API jest czystszym zamiennikiem, XMLHttpRequest
który korzysta z obietnic ES6. Jest ładny wyjaśnienie tutaj , ale sprowadza się do (z artykułu):
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function() {
console.log("Booo");
});
Obsługa przeglądarek jest teraz dobra w najnowszych wydaniach (działa w Chrome, Firefox, Edge (v14), Safari (v10.1), Opera, Safari iOS (v10.3), przeglądarka Android i Chrome na Androida), jednak IE będzie prawdopodobnie nie otrzyma oficjalnego wsparcia. GitHub ma polifill udostępnia który jest zalecany do obsługi starszych przeglądarek, które nadal są w dużej mierze w użyciu (szczególnie wersje Safari sprzed marca 2017 i przeglądarki mobilne z tego samego okresu).
Myślę, że jest to wygodniejsze niż jQuery lub XMLHttpRequest, czy nie, zależy od charakteru projektu.
Oto link do specyfikacji https://fetch.spec.whatwg.org/
Edytować :
Używając asynchronicznego / oczekującego ES7, staje się to po prostu (na podstawie tej Gist ):
async function fetchAsync (url) {
let response = await fetch(url);
let data = await response.json();
return data;
}
fetch(url, { credentials:"include" })
window.fetch
nie jest dostarczany z analizatorem XML, ale możesz samodzielnie przeanalizować odpowiedź, jeśli potraktujesz ją jako tekst (a nie json, jak w powyższym przykładzie). Zobacz stackoverflow.com/a/37702056/66349 dla przykładu
Wersja bez oddzwaniania
var i = document.createElement("img");
i.src = "/your/GET/url?params=here";
setInterval
rozmowę.
Oto kod do zrobienia tego bezpośrednio za pomocą JavaScript. Ale, jak wspomniano wcześniej, lepiej byłoby skorzystać z biblioteki JavaScript. Moim ulubionym jest jQuery.
W poniższym przypadku wywoływana jest strona ASPX (która służy jako usługa REST biednego człowieka) w celu zwrócenia obiektu JSON JavaScript.
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;
}
}
}
Nowoczesna wersja kopiuj-wklej (używając funkcji pobierania i strzałek ) :
//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())
)
)();
Klasyczna wersja kopiuj-wklej:
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);
Krótkie i czyste:
const http = new XMLHttpRequest()
http.open("GET", "https://api.lyrics.ovh/v1/toto/africa")
http.send()
http.onload = () => console.log(http.responseText)
IE będzie buforować adresy URL, aby przyspieszyć ładowanie, ale jeśli, powiedzmy, odpytujesz serwer w odstępach czasu, próbując uzyskać nowe informacje, IE zbuforuje ten adres URL i prawdopodobnie zwróci ten sam zestaw danych, który zawsze miałeś.
Niezależnie od tego, jak ostatecznie wykonasz żądanie GET - waniliowy JavaScript, prototyp, jQuery itp. - upewnij się, że wprowadziłeś mechanizm do walki z buforowaniem. Aby temu przeciwdziałać, dołącz unikalny token na końcu adresu URL, który chcesz trafić. Można to zrobić przez:
var sURL = '/your/url.html?' + (new Date()).getTime();
Spowoduje to dodanie unikatowego znacznika czasu na końcu adresu URL i zapobiegnie buforowaniu.
Prototyp sprawia, że jest to bardzo proste
new Ajax.Request( '/myurl', {
method: 'get',
parameters: { 'param1': 'value1'},
onSuccess: function(response){
alert(response.responseText);
},
onFailure: function(){
alert('ERROR');
}
});
Jedno rozwiązanie obsługujące starsze przeglądarki:
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);
}
}
};
}
Może nieco przesada, ale na pewno skorzystasz z tego kodu.
Stosowanie:
//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();
Nie jestem zaznajomiony z widżetami kodów kreskowych Mac OS, ale jeśli pozwalają one na używanie bibliotek JavaScript i obsługę XMLHttpRequests , użyłbym jQuery i zrobiłbym coś takiego:
var page_content;
$.get( "somepage.php", function(data){
page_content = data;
});
W pliku Info.plist widżetu nie zapomnij ustawić swojego AllowNetworkAccess
klucza na true.
Najlepszym sposobem jest użycie AJAX (prosty tutorial na tej stronie Tizag ). Powodem jest to, że każda inna technika, której możesz użyć, wymaga więcej kodu, nie gwarantuje się pracy w różnych przeglądarkach bez przeróbek i wymaga użycia większej ilości pamięci klienta poprzez otwieranie ukrytych stron w ramkach, przekazując adresy URL analizując ich dane i zamykając je. AJAX jest sposobem na wyjście w tej sytuacji. Że moje dwa lata intensywnego rozwoju javascript mówią.
Dla tych, którzy używają AngularJs , jest to $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.
});
Żądanie HTTP GET można uzyskać na dwa sposoby:
To podejście oparte na formacie xml. Musisz podać adres URL żądania.
xmlhttp.open("GET","URL",true);
xmlhttp.send();
Ten oparty jest na jQuery. Musisz podać adres URL i nazwę funkcji, do której chcesz zadzwonić.
$("btn").click(function() {
$.ajax({url: "demo_test.txt", success: function_name(result) {
$("#innerdiv").html(result);
}});
});
Aby to zrobić, Fetch API jest zalecanym podejściem przy użyciu obietnic JavaScript. XMLHttpRequest (XHR), obiekt IFrame lub znaczniki dynamiczne są starszymi (i bardziej niezgrabnymi) podejściami.
<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>
Oto świetne demo pobierania i dokumenty MDN
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/')
To samo można zrobić w przypadku żądania wysłania.
Spójrz na ten link Żądanie wpisu JavaScript jak formularz
Proste żądanie asynchroniczne:
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();
}
// 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()
Jeśli chcesz użyć kodu widżetu Dashboard i nie chcesz dołączać biblioteki JavaScript do każdego utworzonego widgetu, możesz użyć obiektu XMLHttpRequest, który Safari domyślnie obsługuje.
Jak donosi Andrew Hedges, widget domyślnie nie ma dostępu do sieci; musisz zmienić to ustawienie w info.plist powiązanym z widżetem.
Aby odświeżyć najlepszą odpowiedź od joanna z obietnicą, oto mój kod:
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();
});
}
Możesz to zrobić również z czystym 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();
}
Zobacz: więcej szczegółów: tutorial html5rocks
<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>
Oto alternatywa dla plików XML do ładowania plików jako obiektu i uzyskiwania dostępu do właściwości jako obiektu w bardzo szybki sposób.
XML działa jak drzewo, dobrze? zamiast pisać
<property> value <property>
napisz prosty plik taki jak ten:
Property1: value
Property2: value
etc.
Zapisz plik .. Teraz wywołaj funkcję ....
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();
}
teraz możesz efektywnie uzyskiwać swoje wartości.
getfilecontent('mesite.com/mefile.txt');
window.onload = function(){
if(objectfile !== null){
alert (objectfile.property1.value);
}
}
To tylko mały prezent, który można wnieść do grupy. Dzięki za polubienie :)
Jeśli chcesz przetestować tę funkcję na komputerze PC, uruchom ponownie przeglądarkę, wykonując następujące polecenie (obsługiwane przez wszystkie przeglądarki oprócz safari):
yournavigator.exe '' --allow-file-access-from-files