HTML teil des inhalts eines iframes auslesen

OP #2766280
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.
#2766619
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...
OP #2767667
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
}
#2767681
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...
#2767881
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren