Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  24 2515
Jeg skal lage en enkel webside som i første omgang slår av og på en lysdiode på en Arduino med ethernet shield. Hvis jeg skriver inn adressene manuelt i nettleseren så fungerer det. Jeg har også laget et enkelt form i html som også fungerer, men når jeg trykker på knappen så blir siden min flyttet over til den siden. Dette ønsker jeg ikke.

<form name="test" action="http://192.168.0.222/" method="GET">
<input type="hidden" name="LED" value="1"/>
<input type="submit" value="Lys på" />
</form>

For å slå på lysdiode:
http://192.168.0.222/?LED=0
For å slå av lysdiode:
http://192.168.0.222/?LED=1

Er det mulig å sende en GET forespørsel til en side uten at min siden går til den adressen, men forblir uforandret?
Bruk Javascript (AJAX om du liker buzzwords). jQuery gjør dette ganske enkelt - som f.eks. ved jQuery.get() (http://api.jquery.com/jQuery.get/)
:(){ :|:& };:
trond89's Avatar
Mulig off-topic, men dersom du bruker linux og kjeder deg:

echo -e "GET /?LED=0 HTTP/1.1\n\n" | nc -i 2 192.168.0.222 80
Hva med noe sånt som dette

Kode

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<input type="button" value="Lys på" onclick="$.get('http://192.168.0.222', {LED:1})"/>
Sitat av trond89 Vis innlegg
Mulig off-topic, men dersom du bruker linux og kjeder deg:

echo -e "GET /?LED=0 HTTP/1.1\n\n" | nc -i 2 192.168.0.222 80
Vis hele sitatet...
Testet det på ubuntu serveren min og det fungerte bra det! Klarte slå av og på lysdioden med å bytte mellom 0 og 1 i kommandoen.

Sitat av John B Vis innlegg
Hva med noe sånt som dette

Kode

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<input type="button" value="Lys på" onclick="$.get('http://192.168.0.222', {LED:1})"/>
Vis hele sitatet...
Her har jeg litt mer problemer. Får det ikke helt til. Har lest meg opp og ned på jQuery og prøvd mye forskjellig uten hell. Jeg bestemte meg da for å feilsøke litt. Åpnet wireshark for å se hva som egentlig ble sendt. Begynte å logge, trykket på "Lys på" knappen og sluttet å logge. Men det viste seg at ingenting blir sendt til IP adressen til arduinoen. Jeg prøvde også å skrive adressen inn manuelt og da fant jeg alle pakkene som ble sendt til arduinoen og responsen tilbake.

Så hvorfor sender den ingenting når jeg trykker på knappen? Er det noe feil i koden, eller er det jeg som gjør noe feil?
Noen feilmeldinger i nettleseren?

Kan jo høres ut som om jQuery ikke er lastet f.eks., men umulig å si uten mer kjøtt på benet.
Jeg ville nok brukt javascript/ajax i dette tilfellet, omtrent slik John B foreslar:

Kode

<script>
function led(state)
{
        var xh = window.XMLHttpRequest?
                new XMLHttpRequest() :
                new ActiveXObject("Microsoft.XMLHTTP");
        xh.open("GET", "http://192.168.0.222/?LED=" + state, true);
        xh.send();
}
</script>
<a href="#" onclick="led(1)">on</a>
<a href="#" onclick="led(0)">off</a>
om det absolutt ikke vil funke, så kan du bruke frames (urgh)

Kode

<iframe src="/" width="1" height="1" name="dummy"></iframe>
<a href="http://192.168.0.222/?LED=1" target="dummy">on</a>
<a href="http://192.168.0.222/?LED=0" target="dummy">off</a>
håper noe av det kommer til nytte
Sist endret av tripflag; 31. januar 2012 kl. 22:02. Grunn: var visst ikke localhost nei
Jeg sliter litt med å få det til å fungere. Men tror kanskje jeg har funnet en grunn nå. Leste litt om XMLhttprequest på wiki og der står det følgende: "..for security reasons, requests will only succeed if they are made to the same server that served the original web page". Det er del av same origin policy.

På siden om jQuery står det "Due to browser security restrictions, most 'Ajax' requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, or protocol". men det står også at "Script and JSONP requests are not subject to the same origin policy restrictions."

Jeg har nemlig prøvd alle kodene dere har postet her pluss noen jeg fant på nettet og testet dem mot en lokal fil jeg hadde og da kjørte koden uten problem. Men når jeg byttet ut med IP adressen ville den ikke kjøre. Tok også inn noen alert("test"); for å se at scriptet ble kjørt.

Hva tror dere? Kan det være noe med same origin policy som stopper dette?

Prøvde også med $.getJSON, som dere ser på siden bruker han den til å kontakte en ekstern side og henter data. Men når jeg bruker den mot meg selv må jeg kanskje bruke min eksterne IP adresse?

Jeg prøvde frames metoden din også tripflag, den fungerte. Men den får være en plan b hvis alt annet feiler
Nettleseren gir ingen feilmeldinger. Har prøvd både Opera og IE9.
er nettsiden din på samme server som maskinen som styrer LED? hvis nei: ja, da er det denne policyen som hindrer deg.
Løsning: bruk cURL eller python-scripts på server-siden for å gjøre dette for deg om dette støttes av din webserver. (de fleste webservere støtter i hvertfall cURL, og støtter python om du har SSH-tilgang).

http://php.net/manual/en/book.curl.php

Angående måten ting er satt opp på: Når du implementerer ting på denne måten burde du gjøre det RESTfull. Det vil si at en GET-request egentlig ikke skal endre noen ting på serveren - kun gi deg data. Om du skal endre data gjør du en PUT eller POST-request.

F.eks: GET: http://192.168.0.222/LED - Dette gir deg status om lyset er på eller ikke
POST: http://192.168.0.222/LED med body: "staus=on" eller "status=off" setter leds av eller på.

Dette handler rett og slett om grood practice, som er en god vane og ha med fra begynnelsen. (å ofte bruke snarveier fordi man ikke føler man tjener noe på å gjøre det ordentlig gir deg bare dårlige vaner som kan være vanskelig å bli kvitt)
Slikt oppsettet er nå mens jeg tester ut, så har jeg en ubuntu server med LAMP på som hoster html filene jeg tester. Jeg browser disse fra en windows maskin. Så er Arduinoen også koblet inn på samme ruter. Så det er totalt 3 forskjellige IP adresser. Når jeg (forhåpentligvis) blir ferdig med nettsiden vet jeg ikke hvilken server den skal hostes fra, men om det er nødvendig så er det ikke problem og bare ha den her hos meg.

Skal se om jeg ikke får lest meg litt opp på curl i helgen.
@tripflag

Enig at det er unødvendig å laste inn jQuery for dette. Men koden din er ikke tilpasset andre nettlesere bortsett fra internet explorer.

@trådstarter

Kan ikke se hva det er du prøver å gjøre, men om det er noe effekt på objektene, kan du gjøre det alene med basic css og JS uten å blande inn PHP.
CT705, koden er bekreftet fungerende i både Chrome og firefox, hvertfall på maskinen min. Activexobject-greia er en shorthand fallback dersom xmlhttprequest ikke støþtes av nettleseren (eg. IE*).

Fortsatt et problem med at XSS blokkeres, men ser ingen grunn til at iframe-løsningen min ikke skulle fungere...
Sitat av CT705 Vis innlegg
Kan ikke se hva det er du prøver å gjøre, men om det er noe effekt på objektene, kan du gjøre det alene med basic css og JS uten å blande inn PHP.
Vis hele sitatet...
Det jeg vet er at når jeg går inn på URL'ene i førsteposten så skrur jeg av og på lysdioden på arduino'en min. Nettsiden jeg da kommer til inneholder responsen fra arduinoen, en slags bekreftelse på at lysdioden har blitt skrudd på. Det jeg da ønsker er en knapp som gjør dette for meg. Jeg prøvde å laget et form som du ser i førstepost, men problemet da er at nettsiden min går til denne tomme nettsiden som kun inneholder responsen. Så jeg lurer på om noen vet en metode slik at jeg trykker på knappen også forbli nettsiden min uforandret. Requesten skjer i bakgrunnen. Og eventuelt få responsen inn på en måte.

Sitat av tripflag Vis innlegg
...men ser ingen grunn til at iframe-løsningen min ikke skulle fungere...
Vis hele sitatet...
iframes løsningen din fungerte. som jeg nevnte tidligere, men jeg ser nå at jeg var litt uheldig og svarte på to uavhengige ting i samme avsnitt. Den setningen med at det ikke var feilmeldinger i nettleseren var egentlig ment generelt til alle metodene som ikke har fungert til nå.

Og hvis noen lurer på hvorfor stresse slik bare for å skru av og på noen lysdioder så er lysdiodene bare for å indikere tilstanden til utgangen på mikrokontrolleren. Hvis jeg har en nettside som kan kontrollere en mikrokontroller så kan jeg f.eks. bytte lysdioden ut med et rele og styre lyset i stuen min eller en varmeovn eller hva som helst egentlig.
Sist endret av RubiksRune; 3. februar 2012 kl. 19:17.
Det er umulig å få javascript til å kjøre ajax mot andre URL enn den du er på. Det hjelper ikke å være på samme server, det må være samme URL. Jeg har til og med problemer med www. og ikke www.

Dersom du ikke er på samme URL, er nok iframe eneste brukbare løsning.
Limited edition
Moff's Avatar
Sitat av Jannis! Vis innlegg
Det er umulig å få javascript til å kjøre ajax mot andre URL enn den du er på. Det hjelper ikke å være på samme server, det må være samme URL. Jeg har til og med problemer med www. og ikke www.
Dersom du ikke er på samme URL, er nok iframe eneste brukbare løsning.
Vis hele sitatet...
Det er nok ikke helt riktig. AJAX blokkeres fra å sende mot andre servere, ikke andre filer på samme server. Når jeg jobber med AJAX-løsninger så kjører jeg aldri spørring mot den samme filen (URL-en) som den spørringen kommer fra, fordi koden for å ta imot requesten da måtte ha vært i den samme filen - noe som fort blir veldig rotete. Du kan sende spørringer mot en hvilken som helst fil, så lenge de befinner seg på samme domene. Dette er en sikkerhetspolicy som det er mulig å slå av om du har tilgang til begge serverene, noe trådstarter muligens har.

Det jeg tror er den mest elegante løsningen på dette, er som etse foreslår, å bruke cURL og PHP. PHP er ikke begrenset av noen policy slik Javascript er, og derfor kan du bruke AJAX til å ringe opp serveren, og la serveren ringe opp LED-kontrollen. Her er et kjapt eksempel:

Kode

<?php

// Legg inn URL-ene som skal pinges:
$url_on = 'http://www.google.no/search?q=on';
$url_off = 'http://www.google.no/search?q=off';

// Sjekk om filen åpnes med GET-data eller ikke:
if(isset($_GET['led'])) {
	if($_GET['led'] == 'on') {
		$link = curl_init($url_on);
		curl_exec($link);
		curl_close($link);
	} elseif($_GET['led'] == 'off') {
		$link = curl_init($url_off);
		curl_exec($link);
		curl_close($link);
	}
} else {
// Ikke noe GET-data, så da viser vi layouten i stedet:
?>

<script>
function led(status) {
	// Sett opp et AJAX-objekt:
	var ajax;
	try {
		ajax = new XMLHttpRequest();
	} catch (error) {
		try {
			ajax = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (error) {
			try {
				ajax = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (error) {
				return false;
			}
		}
	}
	// Eksempel på ekstrafunksjon for å sjekke respons fra server:
	ajax.onreadystatechange = function() {
		if(ajax.readyState == 4) {
			// Her kan du håndtere respons hvis du vil, serverdata ligger nå i ajax.responseText-variabelen (string)
		}
	}
	// Send forespørsel til server
	ajax.open("GET", "?led=" + status, true);
	ajax.send();
};
</script>

<!-- Knapper for å starte AJAX-funksjonen: -->
<input type="button" value="På" onclick="led('on')">
<input type="button" value="Av" onclick="led('off')">

<!-- Avslutt else-løkken fra PHP-skriptet -->
<? } ?>
Med forbehold mot skrivefeil. Denne filen sjekker først om det finnes en GET-forespørsel. Hvis det ikke gjør så vises to knapper, på og av. Disse knappene kjører en Javascript-funksjon som bruker AJAX til å åpne dette skriptet på nytt, denne gangen MED en GET-forespørsel. Dette får PHP-skriptet til å starte cURL-funksjonen i stedet for å vise knappene en gang til. If-løkken sjekker om variabelen 'led' er enten 'on' eller 'off', en variabel som sendes fra knappene. Avhengig av hva de er så åpnes én av to mulige URL-er. Jeg bruker tre cURL-funksjoner. curl_init() starter en "cURL-ressurs" med den valgte URL-en. curl_exec() åpner denne URL-en, og curl_close() lukker ressursen.

Jeg har lagt opp til at du kan utvide med å sjekke hva slags respons du får fra serveren og sånn, noe som også er grunnen til at jeg bruker isset-funksjonen på denne måten. Hvis du ikke trenger noe output, så er det egentlig ikke nødvendig å passe på at output fra filen ikke sendes to ganger. Det samme gjelder den litt knotete if-løkka, som egentlig er skrevet for å validere data fra knappene. Hvis du bare skal bruke dette selv, så hadde jeg ikke orket å bry meg om det heller.
Takk for et utfyllende svar Moff. Slikt setter en pris på. Uheldigvis var du litt for sen. Etter Jannis! sitt svar så begynte jeg på en iframes løsning og har tilpasset koden på Arduino og begynner å bli ferdig. Det fungerer brukbart, men med 5 iframes på samme side som sender hver sin status GET forespørsel når du åpner siden så går det litt sakte. Litt morsomt å se ett og ett iframes bli utfylt med GET responsen. Så din versjon Moff hadde nok vært en bedre løsning.

Når det er sagt så testet jeg koden din. Det er det minste jeg kan gjøre når du kommer med et slikt svar. Jeg byttet ut url'ene og fikk opp to knapper som du beskrev, men jeg fikk det ikke helt til å fungere. Den kommer aldri forbi isset testen virker det som. Jeg satte inn en echo før og etter, og bare den første viser.
Ser du har fått mange svar, men jeg må bare svare deg her.
Dette ligner veldig på mine mange prosjekt før i tiden og som jeg har brukt til mangt i flere formater.

Det ser ut som i bunn å grunn du laster data for å trigge LED din? am i right?

Da skulle det vel ikke være værre en så her..

Kode

<a href="<?php file_get_contents("http://192.168.0.222/?LED=0"); ?>"><img name="ledon" src="" width="32" height="32" alt=""></a>

<a href="<?php file_get_contents("http://192.168.0.222/?LED=1"); ?>"><img name="ledoff" src="" width="32" height="32" alt=""></a>
Hadde en ganske utfyllende diskusjon om dette på itpro i sin tid.
http://itpro.no/supportforum/index.php?showtopic=73316

Ikke for at dette er sikkert, korrekt eller fasit på hvordan slikt skal gjøres men det fungerer ganske enkelt

Om det fungerer for deg vet jeg ikke, men om det gjør det er det absolutt enkleste måten å gjøre det på for hjemmebruk. Avansert kan man gjøre det når den tid kommer

Slik holdt jeg på da jeg trengte enkel å kjapp avspilling av lyd i stua når en side lastet på en server et sted i Nederland..
http://bildr.no/view/1105386

ble feil i bilde.. http://bildr.no/view/1105386

Glem de linkene i den koden... php koden jeg skulle fram til

Sånn vil det være ferdig hakket ut med slegge i stein, det er ikke vakkert men du kan bygge hus oppå det

Dette i siden det kjøres fra..

HTML-kode

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function() {
      $("#ledon").click(function(evt) {
         $("#ondivdiv").load("ledon.php");
         evt.preventDefault();
      });
    });

</script>

<script type="text/javascript">
    $(document).ready(function() {
      $("#ledoff").click(function(evt) {
         $("#offdiv").load("ledoff.php");
         evt.preventDefault();
      });
    });

</script>

<a id="ledon" href="#">LED ON</a>
<a id="ledoff" href="#">LED AV</a>

<div id="ondiv"></div>
<div id="offdiv"></div>
2 stk nye filer må til..

ledon.php

Kode

<?php file_get_contents("http://192.168.0.222/?LED=0"); ?>
og..

ledoff.php

Kode

<?php file_get_contents("http://192.168.0.222/?LED=1"); ?>
Så sånn er det
Sist endret av kroider911; 13. februar 2012 kl. 07:43.
Limited edition
Moff's Avatar
Sitat av RubiksRune Vis innlegg
Den kommer aldri forbi isset testen virker det som. Jeg satte inn en echo før og etter, og bare den første viser.
Vis hele sitatet...
Jeg tror dette kan skyldes at du ikke har tilgang til cURL på webserveren din. Hvis du kjører en lokal server med Apache, for eksempel gjennom XAMPP, så er det veldig enkelt å bare slå på cURL uten noen ekstra installasjon. Du kan teste om cURL er tilgjengelig ved å se om start-funksjonen eksisterer:

if(function_exists('curl_init')) {
echo 'cURL er på';
} else {
echo 'cURL er av';
}

Det kan også være fordelaktig å aktivere feilmeldinger, i alle fall midlertidig, sånn at du ser hvor og hvorfor skriptet krasjer. Dette kan gjøres via PHP.ini, eller, som en mer midlertidig løsning, i selve skriptet:

error_reporting(E_ALL);

Hvis du limer inn denne øverst, og ser noe à la "call to undefined function 'curl_init' on line 10...", så må du nok prøve å legge inn cURL-utvidelsen før en slik løsning vil fungere.
Sist endret av Moff; 14. februar 2012 kl. 13:31.
Sitat av kroider911 Vis innlegg
Ser du har fått mange svar, men jeg må bare svare deg her.
Dette ligner veldig på mine mange prosjekt før i tiden og som jeg har brukt til mangt i flere formater.

Det ser ut som i bunn å grunn du laster data for å trigge LED din? am i right?

Da skulle det vel ikke være værre en så her..

Kode

<a href="<?php file_get_contents("http://192.168.0.222/?LED=0"); ?>"><img name="ledon" src="" width="32" height="32" alt=""></a>

<a href="<?php file_get_contents("http://192.168.0.222/?LED=1"); ?>"><img name="ledoff" src="" width="32" height="32" alt=""></a>
Hadde en ganske utfyllende diskusjon om dette på itpro i sin tid.
http://itpro.no/supportforum/index.php?showtopic=73316

Ikke for at dette er sikkert, korrekt eller fasit på hvordan slikt skal gjøres men det fungerer ganske enkelt
Vis hele sitatet...
Bortsett fra at det ikke vil fungere som ønsket... file_get_contents laster inn innholdet og setter inn <a href="HER" …
Det er ikke det TS ønsker, i såfall vil lyset i bestefall blinke hver gang man laster siden, men intet vil skje annet enn at resultatet fra GET (som antageligvis er tilnærmet tomt) vil komme inn i href-egenskapen til a-taggen.

Det han eventuelt ønsker er å sende en GET (uten å laste siden på nytt), akkurat det har han fått en del pekere på over - din løsning er ikke en av de.
Sitat av MrBlaine Vis innlegg
Bortsett fra at det ikke vil fungere som ønsket... file_get_contents laster inn innholdet og setter inn <a href="HER" …
Det er ikke det TS ønsker, i såfall vil lyset i bestefall blinke hver gang man laster siden, men intet vil skje annet enn at resultatet fra GET (som antageligvis er tilnærmet tomt) vil komme inn i href-egenskapen til a-taggen.

Det han eventuelt ønsker er å sende en GET (uten å laste siden på nytt), akkurat det har han fått en del pekere på over - din løsning er ikke en av de.
Vis hele sitatet...
Drit i det les resten av tråden så kansje du skjønner.

GET er en sideforespørsel....

Så om du mener at den ferdige koden nederst i innlegget ikke vil fungere? Har du egentlig lest den?
Sist endret av kroider911; 15. februar 2012 kl. 00:52.
Jeg skjønner det meget godt... som du sier GET er en sideforespørsel.

I stedet for å skrive masser av kode så kan du i praksis bruke det som sto i svar #3 og simple-proxy eller #3 kombinert med de to filene du har laget helt på slutten. Hva jeg skal med de første 25 cm innlegg, vet jeg ikke.
Sitat av MrBlaine Vis innlegg
Jeg skjønner det meget godt... som du sier GET er en sideforespørsel.

I stedet for å skrive masser av kode så kan du i praksis bruke det som sto i svar #3 og simple-proxy eller #3 kombinert med de to filene du har laget helt på slutten. Hva jeg skal med de første 25 cm innlegg, vet jeg ikke.
Vis hele sitatet...
Nettopp.

Nei hva du skal med de første cm. vet ikke jeg, men når det ikke går an å redigere innlegget så blir det slik. Svaret på innlegget står på slutten, les det den som orker ffs.
Først av alt, beklager for mine noe sene svar. Jeg er alt for opptatt om dagene til dette her, hehe.

Sitat av kroider911 Vis innlegg
Slik holdt jeg på da jeg trengte enkel å kjapp avspilling av lyd i stua når en side lastet på en server et sted i Nederland..
http://bildr.no/view/1105386
...
Glem de linkene i den koden... php koden jeg skulle fram til

Sånn vil det være ferdig hakket ut med slegge i stein, det er ikke vakkert men du kan bygge hus oppå det

Dette i siden det kjøres fra..

HTML-kode

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function() {
      $("#ledon").click(function(evt) {
         $("#ondivdiv").load("ledon.php");
         evt.preventDefault();
      });
    });

</script>

<script type="text/javascript">
    $(document).ready(function() {
      $("#ledoff").click(function(evt) {
         $("#offdiv").load("ledoff.php");
         evt.preventDefault();
      });
    });

</script>

<a id="ledon" href="#">LED ON</a>
<a id="ledoff" href="#">LED AV</a>

<div id="ondiv"></div>
<div id="offdiv"></div>
2 stk nye filer må til..

ledon.php

Kode

<?php file_get_contents("http://192.168.0.222/?LED=0"); ?>
og..

ledoff.php

Kode

<?php file_get_contents("http://192.168.0.222/?LED=1"); ?>
Så sånn er det
Vis hele sitatet...
Enkel og kjapp måte for avspilling av lyd i stuen sa du? vel, vi har tydeligvis forskjellig oppfatning av enkelt, hehe. Men creds for oppsettet ditt, skulle likt å sett på det.

Når det gjelder koden så testet jeg den ut. Det skjedde ikke så mye når jeg trykket på linkene jeg laget. Jeg prøvde også å gå inn på ledon.php i nettleseren, men ingenting der heller. Er det meningen at lysdioden skal gå på når jeg går inn på den adressen?


Sitat av Moff Vis innlegg
Jeg tror dette kan skyldes at du ikke har tilgang til cURL på webserveren din.
Vis hele sitatet...
Det kan godt stemme. Jeg installerte det jeg fant av cURL på serveren. Og limte inn koden din, fikk tilbake 'cURL er på'. Så det er bra. Men koden kommer fortsatt ikke forbi isset. Jeg limte curl_exec($link) og curl_close($link) inn før if-testen, og da fungerte det utmerket. Lysdioden skrudde seg av og på ettersom jeg byttet verdien i $link. Jeg satte også inn echo($_GET['led']) og den printer ikke ut noen ting. Prøvde flere forskjellige variabel navn for jeg er litt usikker på hva i koden som er navnet på variabelen og hva som er innholdet. I ajax.open skriver du ("?led=" + status) og da regner jeg med at statusen er med i innholdet av variabelen siden du tester på det i php delen, men ikke "?led="-delen?

Jeg spør egentlig bare på grunn av nysgjerrighet, jeg kommer nok til å bruke iframes løsningen uansett da den er så å si klar. Men hadde vært greit å fått det til å fungere så kan jeg bytte ut løsningen min hvis jeg får tid/lyst en dag.
Limited edition
Moff's Avatar
Sitat av RubiksRune Vis innlegg
Jeg spør egentlig bare på grunn av nysgjerrighet, jeg kommer nok til å bruke iframes løsningen uansett da den er så å si klar. Men hadde vært greit å fått det til å fungere så kan jeg bytte ut løsningen min hvis jeg får tid/lyst en dag.
Vis hele sitatet...
Jeg vet ikke helt hvor mye kunnskap du har om Javascript og PHP fra før, så jeg kan bryte opp koden og forklare så godt jeg får til. Kan jo hende at noen andre finner denne tråden om et år også, for alt vi vet.

Grunnidéen med skriptet jeg postet var å ha en fil som kan gjøre to oppgaver. Hvis fila åpnes med en såkalt query string, eller GET-data, så kjøres en annen kode enn hvis filen åpnes uten GET-data. På nettsider så har man to hovedmåter å sende informasjon på, GET-data og POST-data. Post er mer "usynlig" enn det GET er. Det er som regel POST du bruker når du trykker på knapper, logger inn med brukernavn og passord og slike ting. Hvis du prøver å oppdatere en fil (nettside) som du også har sendt POST-data til, så får du som regel en advarsel om at du er i ferd med å sende dataene én gang til.

GET er litt mer åpent, og i noen tilfeller mer praktisk. Variablene sendes her gjennom selve URL-en (linken). Her på forumet er det for eksempel ekstremt praktisk, ettersom hver tråd du leser genereres av den samme filen på serveren. Det som gjør at du ikke ser den samme tråden hver gang du åpner denne filen, er at variabelen "p" i URL-en har ulike verdier; i denne tråden ser du for eksempel "showthread.php?p=2465045". Filen du har åpnet heter showthread.php, spørsmålstegnet angir at det som kommer etterpå er en query string (GET-data). "p" er variabelnavnet og erlik-tegnet viser hvilken verdi variabelen skal ha. Dette kan i PHP leses slik:

<?php
echo $_GET['p'];
?>

Output fra dette, når du leser denne tråden, vil da bli "2465045".

PHP-skriptet jeg postet er som sagt delt i to hoveddeler; isset()-funksjonen sjekker om variabelen "led" finnes i query stringen. Den skal da i teorien være true hvis du åpner filen med "?led" eller "?led=on" eller "?led=off" og så videre, bakerst i URL-en. isset() sjekker altså ikke hva verdien er for noe, den er true så lenge variabelen er noe annet enn underfinert eller NULL. "?led" vil gjøre at variabelen er en tom string (tilsvarende ""), som betyr at den er definert og ikke NULL. Grunnen til at denne sjekken er nødvendig er at PHP viser en notice (advarsel) hvis du prøver å sammenligne en variabel mot noe som ikke eksisterer. I det tilfellet hvor du åpner filen uten query string, så vil ikke $_GET['led'] eksistere, og if-løkken "if($_GET['led'] == 'on')" vil føre til en notice. Du kan selvsagt ignorere feilmeldinger å la dette være, men jeg synes det er litt dårlig praksis.

Hvis isset() finner at "led" eksisterer, så sjekker en ny if-løkke hva variabelen er satt til, enten "on" eller "off". Dette kommer da fra URL-en, enten "fil.php?led=on" eller "fil.php?led=off". Hvis den er noe annet enn "on" eller "off" så vil ikke skriptet gjøre noe som helst, og bare stanse. I tilfellene hvor den enten er "on" eller "off", så starter cURL-skriptet, som bare åpner én av de to URL-ene for å styre LED-lyset.

Hvis isset() finner at "led" ikke eksisterer, så genererer filen HTML-output, som består av en Javascript-blokk og to knapper. Knappene er veldig enkle, de bruker onclick-funksjonen til å kjøre en Javascript-funksjon kalt "led()". Denne funksjonen er definert i Javascript-blokken øverst;

Kode

function led(status) {
    var ajax;
    try {
        ajax = new XMLHttpRequest();
    } catch (error) {
        try {
            ajax = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (error) {
            try {
                ajax = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (error) {
                return false;
            }
        }
    }



    ajax.onreadystatechange = function() {
        if(ajax.readyState == 4) {
        }
    }



    ajax.open("GET", "?led=" + status, true);
    ajax.send();
};
Her har jeg delt opp koden i tre deler. Den øverste er faktisk bare koden for å lage et AJAX-objekt. Dette er et objekt vi kan bruke til å sende data tilbake til webserveren uten å "oppdatere" nettsiden vi ser på. AJAX kan sende både GET- og POST-data, men i praksis er forskjellen på de to heller liten, siden du med AJAX aldri vil kunne se det som foregår i bakgrunnen (du ser ikke URL-en skriptet åpner når du trykker på knappene). Grunnen til at koden er så lang og merkelig, er at den er bakoverkompatibel, og skal fungere i alle nettlesere som på ett eller annet plan støtter AJAX. Det burde i grunnen holde med å bare si "ajax = new XMLHttpRequest();", men hvis noen prøver seg med en gammel versjon av Internet Explorer, Netscape eller noe slik tøys, så er vi på den trygge siden ved å teste alle andre måter å opprette et AJAX-objekt på. Derav alt dette try-catch styret.

Den miderste kodeblokken er en eksempelkode som ikke har noen funksjon slik jeg har skrevet den. Den første linjen knytter en funksjon til en event som kan skje med AJAX-objektet. Eventen heter "ready state change", som i praksis er statusen til AJAX-objektet. Denne statusen endrer seg når objektet holder på med noe. Enten laster inn, sender data, rapporterer feil eller mottar data. Alle statusene er knyttet til en ID. ID nummber 4 betyr at objektet har mottatt data fra serveren, og med "if(ajax.readyState == 4)" kan vi foreta oss noe når vi har fått svar. Dette kan for eksempel være en bekreftelse fra PHP-skriptet om at LED-lampen er endret. Hvis du for eksempel har mistet tilkoblingen til webserveren, så vil du ikke umiddelbart kunne se det på nettsiden når du har to knapper. Når du trykker på knappene, så vet du heller ikke om AJAX-forespørselen har kommet frem eller ei, spesielt ikke når denne respons-funksjonen ikke er programmert til å foreta seg noe når du får svar.

De to nederste linjene er det som er mest interessant. Den første linjen definerer hva slags og hvilken type data vi sender, og her velger vi GET. Query stringen er "led=" pluss variabelen "status". Vi sender altså ikke "led=status", men heller "led=" pluss hva enn variabelen "status" er satt til. Denne variabelen kommer fra knappene vi trykker på. Som du ser helt øverst i Javascriptet, der vi definerer funksjonen "led":

function led(status)

Her setter vi at variabelen "status" skal settes til det som sendes til funksjonen "led". Knappene er kodet på denne måten:

<input type="button" value="På" onclick="led('on')">

Her ser du på onclick-eventen, at funksjonen "led" åpnes med stringen "on", som betyr at "status" blir satt til "on" når du trykker. Dette sendes videre til ajax.open, og ajax.send() sender forespørselen til PHP-skriptet. Variabelen dukker da opp som $_GET['led'], og cURL-skriptet åpner den valgte URL-en for å slå på LED-lampen.

I psuedo-kode får vi da dette:

Kode

Hvis det finnes GET-data {
	Hvis $_GET['led'] er "on" {
		Ping URL 1
	} Hvis $_GET['led'] er "off" {
		Ping URL 2
	}
} Hvis ikke {
	Opprett AJAX-objekt
	Send AJAX-data
	Knapp 1
	Knapp 2
}
Jeg klarer i farten ikke å se hvor koden brister hen, men det kan i ytterste konsekvens handle om at isset() ikke fungerer så bra sammen med $_GET-arrayet. En skitten hotfix er i så fall å skippe hele isset()-sjekken, og legge inn skillet i den andre if-sjekken, slik:

Kode

<?php

// Legg inn URL-ene som skal pinges:
$url_on = 'http://www.google.no/search?q=on';
$url_off = 'http://www.google.no/search?q=off';

// Sjekk om filen åpnes med GET-data eller ikke:
if($_GET['led'] == 'on') {
	$link = curl_init($url_on);
	curl_exec($link);
	curl_close($link);
} elseif($_GET['led'] == 'off') {
	$link = curl_init($url_off);
	curl_exec($link);
	curl_close($link);
} else {
// Ikke noe GET-data, så da viser vi layouten i stedet:
?>

<script>
function led(status) {
    // Sett opp et AJAX-objekt:
    var ajax;
    try {
        ajax = new XMLHttpRequest();
    } catch (error) {
        try {
            ajax = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (error) {
            try {
                ajax = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (error) {
                return false;
            }
        }
    }
    // Eksempel på ekstrafunksjon for å sjekke respons fra server:
    ajax.onreadystatechange = function() {
        if(ajax.readyState == 4) {
            // Her kan du håndtere respons hvis du vil, serverdata ligger nå i ajax.responseText-variabelen (string)
        }
    }
    // Send forespørsel til server
    ajax.open("GET", "?led=" + status, true);
    ajax.send();
};
</script>

<!-- Knapper for å starte AJAX-funksjonen: -->
<input type="button" value="På" onclick="led('on')">
<input type="button" value="Av" onclick="led('off')">

<!-- Avslutt else-løkken fra PHP-skriptet -->
<? } ?>
Eneste forskjell her er at jeg fjerner isset()-sjekken og legger til else-løkken som tredje alternativ på if-løkken som sjekker "on" og "off". Dette vil imidlertid produsere en notice hvis du har aktivert alle feilmeldinger.
Yes, da fikk jeg det endelig til å fungere med ajax også! Tusen takk Moff for en grundig gjennomgang. Jeg tror nok problemet var den isset testen. For nå når det fungerer så prøvde jeg å lime den inn igjen og da fungerte ingenting. Men det fungerer altså ypperlig nå uten den delen.

Jeg la også inn en til url ($url_status) og en ekstra elseif() som jeg kaller med <body onload="led('status')">. Denne hadde jeg allerede klar på arduinoen, den leser kun av tilstanden på utgangen på arduinoen og sender statusen tilbake når du laster siden.

Så la jeg inn slik at jeg får med responsen. Har et form som printer ut statusen. responsen henter jeg i responseText variabelen som du hadde kommentert. (document.myForm.status.value = ajax.responseText)

Det var vel de endringene jeg la til nå i farten, og det så veldig bra ut. Skal ikke se bort ifra at jeg kommer til å bytte ut iframes løsningen min nå ja. Dere har vært så hjelpsomme her så kanskje jeg legger ut nettsiden her og kobler arduinoen opp så dere kan teste ut hvordan det blir. Men når jeg får koblet til rele og styrer lyset i stuen tror jeg at jeg må få på noe sikkerhet så det ikke blir noe diskotek hos meg.

Her er også koden med de forandringene jeg la inn:

Kode

<?php
// Legg inn URL-ene som skal pinges:
$url_on = 'http://192.168.1.50/?led=1';
$url_off = 'http://192.168.1.50/?led=0';
$url_status = 'http://192.168.1.50/lightStatus';


// Sjekk om filen åpnes med GET-data eller ikke:
if($_GET['led'] == 'on') {
    $link = curl_init($url_on);
    curl_exec($link);
    curl_close($link);
} elseif($_GET['led'] == 'off') {
    $link = curl_init($url_off);
    curl_exec($link);
    curl_close($link);
} elseif($_GET['led'] == 'status') {
    $link = curl_init($url_status);
    curl_exec($link);
    curl_close($link);
} else {
// Ikke noe GET-data, så da viser vi layouten i stedet:
?>

<script>
function led(status) {
    // Sett opp et AJAX-objekt:
    var ajax;
    try {
        ajax = new XMLHttpRequest();
    } catch (error) {
        try {
            ajax = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (error) {
            try {
                ajax = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (error) {
                return false;
            }
        }
    }
    // Eksempel på ekstrafunksjon for å sjekke respons fra server:
    ajax.onreadystatechange = function() {
        if(ajax.readyState == 4) {
            // Her kan du håndtere respons hvis du vil, serverdata ligger nå i ajax.responseText-variabelen (string)
            document.myForm.status.value = ajax.responseText;

        }
    }
    // Send forespørsel til server
    ajax.open("GET", "?led=" + status, true);
    ajax.send();
};
</script>

<!-- Knapper for å starte AJAX-funksjonen: -->

<body onload="led('status')">

Skru på lyset:
<br />
<input type="button" value="På" onclick="led('on')">
<br /><br />
Skru av lyset:
<br />
<input type="button" value="Av" onclick="led('off')">
<br /><br />

<form name='myForm'>
Status: <input type='text' style="border: 0px" name='status' />
</form>

</body>

<!-- Avslutt else-løkken fra PHP-skriptet -->
<? } ?>