Как разрешить междоменные запросы на ESP8266 WebServer

Я использую Raspberry Pi под управлением Chrome (обработка пользовательского интерфейса) и подключаюсь через ajax к совместимому Arduino D1, используя IP - адрес следующим образом:

    $.ajax({
        type: "GET",
        url: "http://10.1.1.100/myfunc?id=5",
        error:  function(jqXHR, exception, response) {
                console.log(exception, response);

        etc...

Недавно я начал получать эту ошибку (интересно, почему этого не происходило в течение последних двух лет):

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://10.1.1.100/myfunc?n=1. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Я пробовал разные вещи, включая настройку браузера (Chrome) на --disable-web-security и различные предложения, здесь и здесь (и многие другие), но я не могу заставить его работать. В настоящее время у меня есть:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
ESP8266WebServer server(80);

void handleRoot() {
  server.send(200, "text/plain", "Root of WebServer!");
}

void setup() {
IPAddress ip(10.1.1.100);
IPAddress gateway(10.1.1.1);
IPAddress subnet(...);
WiFi.begin(ssid, password);
WiFi.config(ip, gateway, subnet);
  // put your setup code here, to run once:
  WiFi.begin(ssid, password);
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  server.on("/", handleRoot);

  server.on("/myfunc", [](){    
    String message = "";
    message += "URI: ";
    message += server.uri();
    message += "\nMethod: ";
    message += (server.method() == HTTP_GET)?"GET":"POST";
    message += "\nArguments: ";
    message += server.args();
    message += "\n";
    for (uint8_t i=0; i<server.args(); i++){
      message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
    }
      String num = server.arg(0);

    server.send(200, "text/plain", message);
 });
  server.on("/myfunc", HTTP_OPTIONS, []() {
    server.sendHeader("Access-Control-Allow-Origin","*")
    server.send(204);
 });

  server.onNotFound(handleNotFound);
  server.begin();
}

void loop() {
  delay(1000);
  ...
  server.handleClient();
}


void handleNotFound(){
  String message = "Error!";
  server.send(404, "text/plain", message);
}

Так что же я делаю не так? Кроме того, одно из осложнений, которое может возникнуть позже, заключается в том, что домен, из которого я вызываю это в ajax, является https, и из того, что я понимаю, https и http несовместимы с междоменными запросами.

Любая помощь приветствуется!

, 👍7

Обсуждение

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS, @Majenko

Thanx @Majenko, но это слишком общее и не относится к сценарию esp8266., @Chiwda

Имеет ли страница, выполняющая Ajax-запрос, заголовки CORS?, @Majenko

добавьте заголовок CORS к каждому ответу, а не только к запросу параметров "предполетная подготовка". @Majenko, только ресурсы, не включенные с другого сервера, нуждаются в заголовках CORS, @Juraj

вам не нужна поддержка ПАРАМЕТРОВ, просто добавьте заголовок ACAO в ответ, @dandavis

@Juraj и @ dandavis Я объединил оба ваших комментария, и теперь это работает! Я удалил часть ОПЦИЙ и поставил server.sendHeader("Access-Control-Allow-Origin","*"); в ответ. Спасибо! Если кто-то из вас захочет облечь это в форму ответа, я буду рад его принять., @Chiwda

@dandavis - уведомлять вас отдельно, потому что SE позволяет уведомлять только одного пользователя за комментарий, @Chiwda


3 ответа


Лучший ответ:

10

Добавьте заголовок CORS к каждому ответу, а не только к запросу параметров "предполетная подготовка". Поддержка ПАРАМЕТРОВ необязательна, но ответ, возвращающий "общий ресурс", должен содержать заголовок CORS

"Access-Control-Allow-Origin: *"

EDIT: с 2020 года библиотека имеет server.EnableCors(true);

,

4

просто добавьте эту строку перед каждым ответом:

server.sendHeader("Access-Control-Allow-Origin", "*");

,

4
server.enableCORS(true);

Сервер добавит заголовок ответа Access-Control-Allow-Origin=*

,

EnableCors был добавлен в 2020 году, @Juraj