Forum: PC-Programmierung HTML teil des inhalts eines iframes auslesen


von hans p. (bluethunder)


Lesenswert?

Hi Leute,

folgendes Problem.
ich habe vor, temperaturen über ein Arduino mit ethernet shield auf 
einer webseite darzustellen.
dazu habe ich z.B. einen button, der mich auf die seite 
http://192.168.1.98/A1 führt. das einzige, was diese seite anzeigt ist 
z.B.:
1
{"A1":"53"}
.
ich würde nun gerne die zahl 53 in einer variable speichern, am besten 
vom typ int, da ich später damit weiterrechnen will.

ich habe zuerst versucht, den kompletten inhalt auszulesen:
1
<html>
2
  <head>
3
    <link rel="shortcut icon" href ="http://dl.dropbox.com/u/68942361/Media/favicon.png">
4
    <title>www.mein-webserver.de.gg</title>
5
  </head>
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7
  <body background="http://dl.dropbox.com/u/68942361/Media/background.jpg">
8
    <h1>
9
      <font color="white"><font face="Arial">Digitale PINs
10
    </h1>
11
   
12
    <script type="text/javascript">
13
        ifrm = document.createElement("IFRAME");
14
        ifrm.setAttribute("src", "http://192.168.1.98/A1");
15
        ifrm.style.width = "100px";
16
        ifrm.style.height = "100px";
17
        ifrm.style.border= "0px";
18
        document.body.appendChild(ifrm); 
19
        var code = ifrm.contentDocument;
20
  alert(code);
21
      
22
    </script>
23
    
24
    </font>
25
  </body>
26
</html>

eigentlich sollte, wie oben schon erwähnt
1
{"A1":"53"}
 ausgegeben werden, es wird jedoch nur
1
[object HTMLDocument]
 ausgegeben.

wäre schön wenn mir jemand helfen könnte.

von Sven (Gast)


Lesenswert?

Evtl muss es heissen:
var code = ifrm.document.value;
oder .title ?
Guck mal hier :
http://de.selfhtml.org/javascript/objekte/document.htm
und hier:
http://de.selfhtml.org/javascript/objekte/document.htm

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Ich vermute mal, daß die Daten im iframe einfach noch nicht
geladen sind.

Lade mal firebug und trace das. Prinzipiell sollte man bei
solchen Sachen immer warten bis das Dokument geladen ist.

von Εrnst B. (ernst)


Lesenswert?

hans peter schrieb:
> {"A1":"53"}

Das ist JSON.
Also würde sich anbieten, das auch als Json einzulesen, statt als 
iframe.

Am Einfachsten per Javascript-Framework (jQuery & co), oder per Hand:
1
var request = new XMLHttpRequest();
2
request.open( "GET", "http://192.168.1.98/A1", true );
3
request.onreadystatechange = function () {
4
    if ( request.readyState == 4 && request.status == 200 ) {
5
            var the_object = JSON.parse( request.responseText );
6
            do_something(the_object);
7
        }
8
};
9
request.send(null);

oder so ähnlich...

von Chris R. (hownottobeseen)


Lesenswert?

Hi,

am besten auf dem abgefragten System noch
1
Access-Control-Allow-Origin: *
im Header ausgeben, damit die Abfrage vom Browser auch erlaubt wird.

Näheres siehe hier: https://developer.mozilla.org/en/http_access_control

HTH

Chris

von hans p. (bluethunder)


Lesenswert?

Danke erstmal für die Antworten, aber ich habe es bis jetzt noch nicht 
zum laufen gebracht.

Ich bin zumindest soweit, dass ich die zielseite so umprogrammieren 
konnte, dass diese nurnoch die zahl, also
1
53
 ausgibt.

alert(code) zeigt aber immernoch
1
[object HTMLDocument]
.

und das mit Access-Control-Allow-Origin: * könnte schwierig werden, ich 
habe nämlich keinen plan wohin damit.
bei der zielseite handelt es sich nämlich um ein arduino, was das ganze 
etwas erschwert.

hier mal der programmcode, vielleicht könnt ihr ja was damit anfangen:
1
#undef DEBUG
2
3
#include "EtherShield.h"
4
5
// please modify the following three lines. mac and ip have to be unique
6
// in your local area network. You can not have the same numbers in
7
// two devices:
8
static uint8_t mymac[6] = { 0x54,0x55,0x58,0x10,0x20,0x35};
9
static uint8_t myip[4] = { 192,168,1,98};
10
11
// listen port for tcp/www (max range 1-254)
12
#define MYWWWPORT 80
13
14
#define BUFFER_SIZE 800
15
static uint8_t buf[BUFFER_SIZE+1];
16
#define STR_BUFFER_SIZE 22
17
static char strbuf[STR_BUFFER_SIZE+1];
18
19
EtherShield es=EtherShield();
20
21
uint16_t http200ok(void)
22
{
23
  return(es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n")));
24
}
25
26
uint16_t http404(void)
27
{
28
  return(es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 404 OK\r\nContent-Type: text/html\r\n\r\n")));
29
}
30
31
// prepare the webpage by writing the data to the tcp send buffer
32
uint16_t print_webpage(uint8_t *buf)
33
{
34
  uint16_t plen;
35
  plen=http200ok();
36
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<html><body><h1>Error 404</h1><p>Diese Seite existiert nicht</body></html>"));
37
38
  return(plen);
39
}
40
41
42
#define CMDBUF 50
43
44
int16_t process_request(char *str)
45
{
46
  int8_t r=-1;
47
  int8_t i = 0;
48
  char clientline[CMDBUF];
49
  int index = 0;
50
  int plen = 0;
51
  
52
#ifdef DEBUG
53
// Serial.println( str );
54
#endif
55
56
  char ch = str[index];
57
  
58
  while( ch != ' ' && index < CMDBUF) {
59
    clientline[index] = ch;
60
    index++;
61
    ch = str[index];
62
  }
63
  clientline[index] = '\0';
64
65
#ifdef DEBUG
66
  Serial.println( clientline );
67
#endif
68
69
  // convert clientline into a proper
70
  // string for further processing
71
  String urlString = String(clientline);
72
73
  // extract the operation
74
  String op = urlString.substring(0,urlString.indexOf(' '));
75
76
  // we're only interested in the first part...
77
  urlString = urlString.substring(urlString.indexOf('/'), urlString.indexOf(' ', urlString.indexOf('/')));
78
79
  // put what's left of the URL back in client line
80
  urlString.toCharArray(clientline, CMDBUF);
81
82
  // get the first two parameters
83
  char *pin = strtok(clientline,"/");
84
  char *value = strtok(NULL,"/");
85
86
  // this is where we actually *do something*!
87
  char outValue[10] = "MU";
88
  //outValue = "MU";
89
// String jsonOut = String();
90
  char jsonOut[50];
91
92
  if(pin != NULL){
93
    if(value != NULL){
94
95
      // set the pin value
96
#ifdef DEBUG
97
      Serial.println("setting pin");
98
#endif
99
            
100
      // select the pin
101
      int selectedPin = pin[0] -'0';
102
#ifdef DEBUG
103
      Serial.println(selectedPin);
104
#endif
105
            
106
      // set the pin for output
107
      pinMode(selectedPin, OUTPUT);
108
            
109
      // determine digital or analog (PWM)
110
      if(strncmp(value, "HIGH", 4) == 0 || strncmp(value, "LOW", 3) == 0){
111
              
112
        // digital
113
#ifdef DEBUG
114
        Serial.println("digital");
115
#endif
116
              
117
        if(strncmp(value, "HIGH", 4) == 0){
118
#ifdef DEBUG
119
          Serial.println("HIGH");
120
#endif
121
          digitalWrite(selectedPin, HIGH);
122
        }
123
              
124
        if(strncmp(value, "LOW", 3) == 0){
125
#ifdef DEBUG
126
          Serial.println("LOW");
127
#endif
128
          digitalWrite(selectedPin, LOW);
129
        }
130
              
131
      } else {
132
              
133
        // analog
134
#ifdef DEBUG
135
        Serial.println("analog");
136
#endif
137
              
138
        // get numeric value
139
        int selectedValue = atoi(value);
140
#ifdef DEBUG
141
        Serial.println(selectedValue);
142
#endif
143
              
144
        analogWrite(selectedPin, selectedValue);
145
              
146
      }
147
      // return status
148
      return( http200ok() );
149
        
150
    } else {
151
152
      // read the pin value
153
#ifdef DEBUG
154
      Serial.println("reading pin");
155
#endif
156
157
      // determine analog or digital
158
      if(pin[0] == 'a' || pin[0] == 'A'){
159
160
        // analog
161
        int selectedPin = pin[1] - '0';
162
163
#ifdef DEBUG
164
        Serial.println(selectedPin);
165
        Serial.println("analog");
166
#endif
167
168
        sprintf(outValue,"%d",analogRead(selectedPin));
169
              
170
#ifdef DEBUG
171
        Serial.println(outValue);
172
#endif
173
174
      } else if(pin[0] != NULL) {
175
176
        // digital
177
        int selectedPin = pin[0] - '0';
178
179
#ifdef DEBUG
180
        Serial.println(selectedPin);
181
        Serial.println("digital");
182
#endif
183
184
        pinMode(selectedPin, INPUT);
185
              
186
        int inValue = digitalRead(selectedPin);
187
              
188
        if(inValue == 0){
189
          sprintf(outValue,"%s","LOW");
190
          //sprintf(outValue,"%d",digitalRead(selectedPin));
191
        }
192
              
193
        if(inValue == 1){
194
          sprintf(outValue,"%s","HIGH");
195
        }
196
              
197
#ifdef DEBUG
198
        Serial.println(outValue);
199
#endif
200
      }
201
202
      // assemble the json output
203
      sprintf( jsonOut, "%s", outValue );
204
#ifdef DEBUG
205
      Serial.println( jsonOut );
206
#endif
207
      // return value
208
      plen=http200ok();
209
      plen=es.ES_fill_tcp_data(buf,plen,jsonOut);
210
      return(plen);
211
    }
212
  } else {
213
          
214
    // error
215
#ifdef DEBUG
216
    Serial.println("erroring");
217
#endif
218
    plen = http404();
219
  }
220
 
221
  return plen;
222
}
223
224
225
226
void setup(){
227
  // Init SPI
228
   es.ES_enc28j60SpiInit();
229
  
230
  // initialize enc28j60
231
  es.ES_enc28j60Init(mymac); //, 8);
232
233
  //init the ethernet/ip layer:
234
  es.ES_init_ip_arp_udp_tcp(mymac,myip,80);
235
236
#ifdef DEBUG
237
  Serial.begin(19200);
238
  Serial.println("ENC28J60 RESTduino");
239
240
  Serial.print( "ENC28J60 version " );
241
  Serial.println( es.ES_enc28j60Revision(), HEX);
242
  if( es.ES_enc28j60Revision() <= 0 )
243
    Serial.println( "Failed to access ENC28J60");
244
#endif
245
246
#ifdef DEBUG
247
  Serial.println("Ready");
248
#endif
249
250
}
251
252
void loop(){
253
  uint16_t plen, dat_p;
254
  int8_t cmd;
255
256
  while(1) {
257
    // read packet, handle ping and wait for a tcp packet:
258
   dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
259
260
    /* dat_p will be unequal to zero if there is a valid http get */
261
    if(dat_p==0){
262
      // no http request
263
      continue;
264
    }
265
266
    // tcp port 80 begin
267
    if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
268
      // head, post and other methods:
269
      dat_p = print_webpage(buf);
270
      goto SENDTCP;
271
    }
272
273
    // just one web page in the "root directory" of the web server
274
    if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
275
#ifdef DEBUG
276
      Serial.println("GET / request");
277
#endif
278
      dat_p=print_webpage(buf);
279
      goto SENDTCP;
280
    }
281
    dat_p = process_request((char *)&(buf[dat_p+4]));
282
    
283
SENDTCP:
284
285
    es.ES_www_server_reply(buf,dat_p); // send web page data
286
    // tcp port 80 end
287
  }
288
289
}

von Εrnst B. (ernst)


Lesenswert?

Dein Haupt-Problem ist das Sicherheits-Modell des Browsers.

Weil die Webseite "boeserhacker.xx" nicht auf den Inhalt eines Frames 
von "sparkasse.de" zugreifen können soll, darf auch deine Webseite von 
"meinwebserver.gg" eben nicht auf den Frameinhalt von "192.168.1.98" 
Zugreifen.

Eine Lösung: Deine Seite gibt folgenden Text aus:
> window.A=53;

Deine Webseite erzeugt dynamisch immer wieder ein script-tag
<script type="text/javascript" source="http://192.168.1.98/A1">;.

Nach dem "window.A=53" ausgeführt wurde, kannst du aus deinem Script 
heraus direkt auf diese Variable zugreifen.

Alternativ kann das script vom Arduino auch einfach einen 
Funktionsaufruf enthalten, wie z.B. "update_display(53);"...
die Funktion selber kann dann wieder vom normalen Webserver kommen...

von Chris R. (hownottobeseen)


Lesenswert?

hans peter schrieb:
> alert(code) zeigt aber immernoch[object HTMLDocument].

ja, du greifst auch nur auf das DOM-Element des Dokuments zu.
Was du möchtest wäre document.body.innerHTML, aber ich behaupte einfach 
mal, das willst du nicht. ;) *

hans peter schrieb:
> und das mit Access-Control-Allow-Origin: * könnte schwierig werden, ich
> habe nämlich keinen plan wohin damit.
> bei der zielseite handelt es sich nämlich um ein arduino, was das ganze
> etwas erschwert.

Genau da muss es hin:

hans peter schrieb:
> uint16_t http200ok(void)
> {
>   return(es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: 
text/html\r\nPragma: no-cache\r\n\r\n")));
> }

Also:
1
HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\nAccess-Control-Allow-Origin: *\r\n\r\n

*) Ehrlich, machs über XmlHttpRequests, wie an anderer Stelle schon 
vorgeschlagen. Über IFrames kann es zwar funktionieren, aber jeder 
Browser behandelt sie anders und dann auch teilweise so, dass man nicht 
richtig auf den IFrame zugreifen kann (Gründe wurden ja schon genannt).

<gebetsmuehle>
Wenn du in Javascript halbwegs vernünftig einsteigen willst:
- Firefox + Firebug
- SelfHtml (Abteilung Javascript)
- https://developer.mozilla.org/de/
</gebetsmuehle>

HTH,

Chris

von hans p. (bluethunder)


Lesenswert?

Naja da ich oben genanntes nicht zum laufen bekomme, habe ich die werte 
vom arduino selbst verarbeiten und so ausgeben lassen, wie ich es 
eigentlich via html machen wollte. kommt aufs gleiche raus :D

Trotzdem danke für eure bemühungen!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.