Неподготовлено (в обещании) TypeError: не удалось получить и ошибку Cors

возникла проблема с возвратом данных из базы данных. Я стараюсь объяснить эту проблему.

1. Если я оставлю "режим" : "no-cors" внутри кода ниже, я могу получить данные с сервера с помощью Postman, но не с моего собственного сервера. Думаю, это должна быть ошибка моей клиентской стороны.

  1. Когда я удаляю "режим" : "no-cors" , тогда у меня возникают 2 ошибки: -Fetch API не может загрузить http://localhost:3000/. Запрос заголовка поля доступа-control-allow-origin не разрешен заголовками Access-Control-Allow-Headers в предполетном ответе. -Uncaught (в обещании) TypeError: Не удалось получить

Быстрый просмотр предложил поставить в "режим" : "no-cors" , который исправил эту ошибку, но это не правильно.

Итак, я подумал, может быть, у кого-то есть предложение, как подойти к этой проблеме.

Надеюсь, я был достаточно ясен, но, конечно, я не даю здесь ясного объяснения: S

function send(){
    var myVar = {"id" : 1};
    console.log("tuleb siia", document.getElementById('saada').value);
    fetch("http://localhost:3000", {
        method: "POST",
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Content-Type": "text/plain"
        },//"mode" : "no-cors",
        body: JSON.stringify(myVar)
        //body: {"id" : document.getElementById('saada').value}
    }).then(function(muutuja){

        document.getElementById('väljund').innerHTML = JSON.stringify(muutuja);
    });
}

Ответ 1

Добавление mode:'no-cors' к заголовку запроса гарантирует, что ответ не будет доступен в ответе

При добавлении "нестандартного" заголовка строка 'access-control-allow-origin' вызовет запрос предварительной проверки OPTIONS, который ваш сервер должен правильно обработать, чтобы запрос POST даже был отправлен

Вы также делаете неправильно fetch... fetch возвращает "обещание" для объекта Response, у которого есть создатели обещаний для json, text и т.д., В зависимости от типа контента...

Короче говоря, если ваша серверная сторона правильно обрабатывает CORS (что из вашего комментария предполагает, что это так), то должно работать следующее

function send(){
    var myVar = {"id" : 1};
    console.log("tuleb siia", document.getElementById('saada').value);
    fetch("http://localhost:3000", {
        method: "POST",
        headers: {
            "Content-Type": "text/plain"
        },
        body: JSON.stringify(myVar)
    }).then(function(response) {
        return response.json();
    }).then(function(muutuja){
        document.getElementById('väljund').innerHTML = JSON.stringify(muutuja);
    });
}

однако, поскольку ваш код на самом деле не заинтересован в JSON (он все-таки строковый объект) - это проще сделать

function send(){
    var myVar = {"id" : 1};
    console.log("tuleb siia", document.getElementById('saada').value);
    fetch("http://localhost:3000", {
        method: "POST",
        headers: {
            "Content-Type": "text/plain"
        },
        body: JSON.stringify(myVar)
    }).then(function(response) {
        return response.text();
    }).then(function(muutuja){
        document.getElementById('väljund').innerHTML = muutuja;
    });
}

Ответ 2

См. описание mozilla.org о том, как работает CORS.

Вам понадобится ваш сервер для отправки правильных заголовков ответа, например:

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization

Помните, что вы можете использовать "*" для Access-Control-Allow-Origin, который будет работать, только если вы пытаетесь передать данные аутентификации. В этом случае вам нужно явно указать исходные домены, которые вы хотите разрешить. Чтобы разрешить несколько доменов, см. этот пост

Ответ 3

вы можете использовать решения, не добавляя "Access-Control-Allow-Origin": "*", если ваш сервер уже использует прокси-шлюз, эта проблема не произойдет, потому что фронт и бэкенд будут маршрутами в одном и том же IP-адресе и на стороне клиента но для разработки вам нужно одно из этих трех решений, если вам не нужен дополнительный код 1-, который имитирует реальную среду с помощью прокси-сервера и настраивает фронт и бэкэнд в том же порту

2-, если вы используете Chrome, вы можете использовать расширение Allow-Control-Allow-Origin: *, это поможет вам избежать этой проблемы

3- вы можете использовать код, но некоторые версии браузеров могут не поддерживать это, поэтому попробуйте использовать одно из предыдущих решений

лучшее решение использует прокси-сервер, такой как ngnix, его легко настроить, и он будет имитировать реальную ситуацию в производственном развертывании

Ответ 4

В моем случае проблема была в протоколе. Я пытался вызвать URL-адрес сценария с http вместо https.