Как разрешить междоменные запросы на 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 несовместимы с междоменными запросами.
Любая помощь приветствуется!
@Chiwda, 👍7
Обсуждение3 ответа
Лучший ответ:
Добавьте заголовок CORS к каждому ответу, а не только к запросу параметров "предполетная подготовка". Поддержка ПАРАМЕТРОВ необязательна, но ответ, возвращающий "общий ресурс", должен содержать заголовок CORS
"Access-Control-Allow-Origin: *"
EDIT: с 2020 года библиотека имеет server.EnableCors(true);
просто добавьте эту строку перед каждым ответом:
server.sendHeader("Access-Control-Allow-Origin", "*");
server.enableCORS(true);
Сервер добавит заголовок ответа Access-Control-Allow-Origin=*
EnableCors
был добавлен в 2020 году, @Juraj
- Почему мы используем client.flush() в коде, когда мы подключаем Esp8266 к Интернету или серверу?
- Управление реле 5В с помощью Wemos D1 R1
- Создать один сервер в режиме точки доступа, а другой - в режиме станции.
- Веб-сервер ESP8266 недоступен через 2 минуты после сброса
- Веб-сервер ESP8266 отображает только текст, даже если тип контента — текст/HTML.
- Веб-сервер ESP8266 не отвечает
- Ошибка при компиляции скетча для Arduino Uno (ld return 1)
- Wemos D1 mini зависает через несколько минут
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