Переадресация при переходе.

VaDoSiQ
VaDoSiQ аватар
Offline
Зарегистрирован: 19.01.2017

Здравствуйте. Имеется скетч, работы ардуино с модулем реле через интернет шилд. Есть адреса типа Relay_1, Relay_2 и т.д. Тоесть я перехожу по адресу http://site.ru/Relay_1 и реле включается, перехожу еще раз, выключается. Принцип понятен. В общем мне нужно чтобы при переходе по данным URL, меня переадресовывало на нужную мне страницу или адрес. Как реализовать?

Собственно сам скетч:

#include <SPI.h> 
#include <Ethernet.h>
#define PIN5 5
#define PIN6 6
#define PIN7 7
#define PIN8 8
#define PIN9 9

byte MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress IP(10, 10, 1, 170);

EthernetServer server(7000);

String Relay;
 
 void setup() { 
  
  Serial.begin(9600);
  pinMode(PIN5, OUTPUT);
  digitalWrite(PIN5, HIGH);
  pinMode(PIN6, OUTPUT);
  digitalWrite(PIN6, HIGH);
  pinMode(PIN7, OUTPUT);
  digitalWrite(PIN7, HIGH);
  pinMode(PIN8, OUTPUT);
  digitalWrite(PIN8, HIGH);
  pinMode(PIN9, OUTPUT);
  digitalWrite(PIN9, HIGH);
  Ethernet.begin(MAC, IP);
  server.begin();
  
 } 
 
 void loop() {
  EthernetClient client = server.available(); 
  if (client) { 
    while (client.connected()) {
      if (client.available()) {
        char query = client.read(); 
        if (Relay.length() < 100) { 
          Relay += query; 
          Serial.print(query); 
          }
          if (query == '\n') {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html"); 
            client.println("<html>"); 
            client.println(); 
            client.println("<head>"); 
            client.println("</head>"); 
            client.println("<body>"); 
            client.println("</body>"); 
            client.println("</html>"); 
            delay(1);
            client.stop();
            if(Relay.indexOf("Relay_1") > 0) {
              digitalWrite(PIN5, ! digitalRead(PIN5));
              }
              if(Relay.indexOf("Relay_2") > 0) {
                digitalWrite(PIN6, ! digitalRead(PIN6));
                }
              if(Relay.indexOf("Relay_3") > 0) {
                digitalWrite(PIN7, ! digitalRead(PIN7));
                }
              if(Relay.indexOf("Relay_4") > 0) {
                digitalWrite(PIN8, ! digitalRead(PIN8));
                }
              if(Relay.indexOf("Relay_5") > 0) {
                digitalWrite(PIN9, ! digitalRead(PIN9));
                }
                Relay = "";
          }
      }
    }
  }
 }

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Вернуть браузеру HTML-код, который заставит его перейти: https://stackoverflow.com/questions/27895424/auto-redirect-to-another-html-page

VaDoSiQ
VaDoSiQ аватар
Offline
Зарегистрирован: 19.01.2017

sadman41 пишет:

Вернуть браузеру HTML-код, который заставит его перейти: https://stackoverflow.com/questions/27895424/auto-redirect-to-another-html-page

А можно конкретнее? Желательно с примером. Я уже пробовал вставлять подобного рода код, ардуино ругается на него. Можете подсказать как правильно его вставлять? С client.println или просто println?

sadman41
Offline
Зарегистрирован: 19.10.2016

Так не экранировали кавычки, поди, как следует: client.println("<meta http-equiv=\"refresh\" content=\"5; url=http://example.com/\">");

Только не втыкайте его куда попало, у <meta> есть свое место в структуре HTML (см. справку по этому тэгу). 

 
VaDoSiQ
VaDoSiQ аватар
Offline
Зарегистрирован: 19.01.2017

sadman41 пишет:

Так не экранировали кавычки, поди, как следует: client.println("<meta http-equiv=\"refresh\" content=\"5; url=http://example.com/\">");

Только не втыкайте его куда попало, у <meta> есть свое место в структуре HTML (см. справку по этому тэгу). 

 

 

Вот так не работает

if(Relay.indexOf("Relay_1") > 0) {
              digitalWrite(PIN5, ! digitalRead(PIN5));
              client.println("<meta http-equiv=\"refresh\" content=\"0; url=http://example.com/relay.html\">");
              }

 

sadman41
Offline
Зарегистрирован: 19.10.2016

И не должно.  Я второй абзац, думаете, написал чтобы место в посте заполнить?

VaDoSiQ
VaDoSiQ аватар
Offline
Зарегистрирован: 19.01.2017

sadman41 пишет:

И не должно.  Я второй абзац, думаете, написал чтобы место в посте заполнить?

А так будет работать?

#include <SPI.h> 
#include <Ethernet.h>
#define PIN5 5
#define PIN6 6
#define PIN7 7
#define PIN8 8
#define PIN9 9

byte MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress IP(10, 10, 1, 170);

EthernetServer server(7000);

String Relay;
 
 void setup() { 
  
  Serial.begin(9600);
  pinMode(PIN5, OUTPUT);
  digitalWrite(PIN5, HIGH);
  pinMode(PIN6, OUTPUT);
  digitalWrite(PIN6, HIGH);
  pinMode(PIN7, OUTPUT);
  digitalWrite(PIN7, HIGH);
  pinMode(PIN8, OUTPUT);
  digitalWrite(PIN8, HIGH);
  pinMode(PIN9, OUTPUT);
  digitalWrite(PIN9, HIGH);
  Ethernet.begin(MAC, IP);
  server.begin();
  
 } 
 
 void loop() {
  EthernetClient client = server.available(); 
  if (client) { 
    while (client.connected()) {
      if (client.available()) {
        char query = client.read(); 
        if (Relay.length() < 100) { 
          Relay += query; 
          Serial.print(query); 
          }
          if (query == '\n') {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html"); 
            client.println("<html>"); 
            client.println(); 
            client.println("<head>");
		if(Relay.indexOf("Relay_1") > 0) {
                digitalWrite(PIN5, ! digitalRead(PIN5));
		client.println("<meta http-equiv=\"refresh\" content=\"5; url=http://example.com/\">");
              }
              if(Relay.indexOf("Relay_2") > 0) {
                digitalWrite(PIN6, ! digitalRead(PIN6));
                }
              if(Relay.indexOf("Relay_3") > 0) {
                digitalWrite(PIN7, ! digitalRead(PIN7));
                }
              if(Relay.indexOf("Relay_4") > 0) {
                digitalWrite(PIN8, ! digitalRead(PIN8));
                }
              if(Relay.indexOf("Relay_5") > 0) {
                digitalWrite(PIN9, ! digitalRead(PIN9));
                }
	    Relay = "";
            client.println("</head>"); 
            client.println("<body>"); 
            client.println("</body>"); 
            client.println("</html>"); 
            delay(1);
            client.stop();
          }
      }
    }
  }
 }

 

negavoid
Offline
Зарегистрирован: 09.07.2016

Намудрили-то :)

client.println("HTTP/1.1 302 Found");
client.println("Location: хттп://ya.ru");

и всё.

sadman41
Offline
Зарегистрирован: 19.10.2016

Строго говоря - это не по стандарту.

-------------------------
302 Moved Temporarily

   The requested resource resides temporarily under a different URL.
   Since the redirection may be altered on occasion, the client should
   continue to use the Request-URI for future requests.
-------------------------

Клиент, руководствуясь RFC, должен сделать _такой же запрос_, по другому адресу, ориентируясь на то, что по предыдущему его запрос не обработан. Тут же запрос отработан и необходим последующий редирект.

К тому же необходимо принять во внимание, что в RFC есть условия, которые могут вызвать неисполнение агентом перехода по 302 code.

Если уж завязываться на HTTP headers, то более правильно и предсказуемо применить Refresh в заголовке HTTP, что и делает, вобщем-то, <meta ... refresh>.

https://en.wikipedia.org/wiki/URL_redirection#Refresh_Meta_tag_and_HTTP_...

Но проблемы с заголовками HTTP отлавливать сложнее и ТС проще воспользоваться HTML-эквивалентом, на мой взгляд.

negavoid
Offline
Зарегистрирован: 09.07.2016

Ради Готта, как угодно, хоть window.location, ах да, ведь джаваскрипт на клиенте тоже исполнят не все.

sadman41 пишет:
Если уж завязываться на HTTP headers, то более правильно и предсказуемо применить Refresh в заголовке HTTP, что и делает, вобщем-то, <meta ... refresh>

Ммм? Применить refresh в заголовке http - выдать 301, а не 302? Назовите-ка мне сервер, который понимает, что в отдаваемой странице присутствует <meta refresh> и поэтому выдаёт код http 301 или 302?

А раз уж придрались, а скажите-ка, кто для вас главнее - IETF или W3C? :)

https://www.w3.org/TR/WCAG10-CORE-TECHS/#auto-page-refresh

sadman41
Offline
Зарегистрирован: 19.10.2016

Я не придрался, а высказал свое мнение. Каждый волен применять в своём ПО то решение, которое ему кажется более красивым визуально. Так же я в курсе ситуации, когда нетскейп продавливал свои стандарты, а майкрософт - свои и отголоски этой битвы до сих пор гремят в браузерах. Поэтому влезать в этот срач, которому уж третий десяток, я не собираюсь.

Однако выдать 302 вместо 200 при фактически выполненном запросе я считаю алогичным.

К тому же не совсем понятно отчего вы Refresh безусловно приравняли к 301.