запрос на выборку не работает с заголовками

Я работаю над страницей входа в систему с веб-службами ReactJs, Spring Boot и rest. Мое интерфейсное приложение Reactjs работает на порту 8080, в то время как мое приложение загрузки веб-службы / Spring работает на порту 9090. Я пытаюсь использовать метод "выборки" для подключения с моим внутренним кодом, но я столкнулся с ошибкой при передаче заголовков в запросе на выборку. Если я удалю свойство заголовков, выполнение перейдет в вызванный внутренний метод. Мне нужно передать заголовки в методе выборки, поскольку это необходимо для доступа к ним в методе веб-службы.

Найдите снимок сетевых запросов и ответов. Без заголовков С заголовками

Ниже мой код файла React JSX:

import React, { Component } from 'react';
class App extends Component {

    constructor(props){
        super(props);
        this.state={
            email:'',
            password:''
        }
        this.handleClick = this.handleClick.bind(this);
   }

    handleClick(){

       var usernameFieldValue = this.refs.emailField.value;
       var passwordFieldValue = this.refs.passwordField.value;
       this.setState({email:usernameFieldValue})
       this.setState({password:passwordFieldValue})

       //var headers = 'Basic bmltZXNoLnBhdGVsQHRhdHZhc29mdC5jb206cGFzc3dvcmQ=';
       //alert(headers);
        fetch('http://192.168.0.239:9090/ws/login',{
            mode: 'cors',
            method: 'get',
            headers: {
                "Content-Type": "application/json",
                "Authorization": "Basic bmltZXNoLnBhdGVsQHRhdHZhc29mdC5jb206cGFzc3dvcmQ="    
            }
        }).then((response) => response.json())
        .then((responseJson) => {
           alert(" responseJson : " + responseJson);
          })
          .catch((error) => {
            alert("Error : " +error);
          });
    }    

    render() {
      return (
              <div id="loginFrame">
                  <div className="container">
                      <div id="loginHeader" className="row">
                          <div className="col-xs-12 text-center">
                              <img src="" alt="'Logo" />
                          </div>
                      </div>
                      <div id="loginBody" className="row">
                      <div className="col-xs-6 col-xs-offset-3">
                          <div className="center-block">
                              <div id="login-panel">
                                  <form id="loginForm" className="form-horizontal" role="form">
                                      <div className="form-group">
                                          <input type="text" className="form-control input-lg" id="email" name="email" ref="emailField" placeholder="Email address"/>
                                      </div>
                                      <div className="form-group">
                                          <input type="password" className="form-control input-lg" id="password" name="password" ref="passwordField" placeholder="Password"/>
                                      </div>
                                      <div className="form-group">
                                          <button onClick={this.handleClick} className="btn btn-lg btn-success pull-right">Login</button>
                                      </div>
                                  </form>
                              </div>
                          </div>
                        </div>
                      </div>
                  </div>
              </div>
      );
   }
}

export default App;

person Dhaval    schedule 25.01.2018    source источник
comment
Что за ошибка?   -  person Umesh    schedule 25.01.2018
comment
Если я включаю заголовок, вызов fetch не работает. и если я не использую заголовки, это вызывает у меня ошибку: TypeError: Failed to fetch error. @Umesh   -  person Dhaval    schedule 25.01.2018
comment
method должно быть GET, а не get, я думаю.   -  person Umesh    schedule 25.01.2018
comment
Я изменил его с помощью «ПОЛУЧИТЬ». По-прежнему сталкиваюсь с той же проблемой.   -  person Dhaval    schedule 25.01.2018
comment
Для Fetch требуется объект Headers, например var h = новые заголовки (). См. MDN: developer.mozilla.org/en-US/docs / Web / API / Fetch_API / Using_Fetch   -  person dannyjolie    schedule 25.01.2018
comment
Я также пробовал @dannyjolie   -  person Dhaval    schedule 25.01.2018
comment
Я действительно запутался .... ваш снимок экрана без заголовков показывает сбой запроса (предположительно на стороне клиента, потому что статус отменен), но снимок экрана с заголовками работает, хотя и без фактических заголовков, которые вы включили в запрос. Вы можете прояснить, что именно происходит? Ярлыки скриншотов перевернуты? Также проверьте консоль Javascript на наличие ошибок.   -  person ccnokes    schedule 26.01.2018
comment
@Dhaval, можете ли вы проверить, что ваш backend api работает нормально. Например, с помощью почтальона и т. Д.   -  person Umesh    schedule 26.01.2018
comment
@Umesh Да, я проверил это с почтальоном. Я получаю от этого соответствующий ответ. Итак, backend api работает правильно.   -  person Dhaval    schedule 29.01.2018
comment
@ccnokes Надписи на скриншотах правильные. Я получаю эту ошибку в консоли при использовании заголовков: Fetch API не может загрузить 192.168.0.239:9090/ws/login. Ответ на предполетный запрос не проходит проверку контроля доступа: на запрошенном ресурсе отсутствует заголовок Access-Control-Allow-Origin. Следовательно, к источнику 'localhost: 8080' не разрешен доступ. Если непрозрачный ответ соответствует вашим потребностям, установите для режима запроса значение «no-cors», чтобы получить ресурс с отключенным CORS.   -  person Dhaval    schedule 29.01.2018
comment
Я также пробовал этот трюк, и теперь я могу успешно запустить запрос с заголовком, но это конфигурация браузера для разработки. Мне это нужно для производственной среды. stackoverflow.com/questions/3102819/   -  person Dhaval    schedule 29.01.2018


Ответы (2)


Вам не нужен mode: cors, это значение по умолчанию.

const headers = new Headers({
  "Content-Type": "application/json",
  "Authorization": "Basic bmltZXNoLnBhdGVsQHRhdHZhc29mdC5jb206cGFzc3dvcmQ="  
});

fetch('http://192.168.0.239:9090/ws/login', {
  method: 'GET',
  headers,
}).then().then().catch();
person Dan    schedule 25.01.2018
comment
Это все еще не работает. Я уже проверил с вариантом удаления mode: cors. Выборка не работает, если я включаю заголовки в свой метод выборки. @Dan - person Dhaval; 25.01.2018
comment
Вы видите сетевой запрос в своих инструментах разработчика? Есть ошибки консоли? - person Dan; 25.01.2018
comment
Я добавил снимки сетевых запросов и ответов для обоих случаев (с заголовками и без них) - person Dhaval; 25.01.2018
comment
С включенным заголовком он показывает мне ОК с кодом 200, но на самом деле запрос не запускается на стороне сервера. Он будет напрямую отлавливаться методом Error ниже метода выборки. - person Dhaval; 25.01.2018
comment
Проблема не обязательно может быть связана с выборкой, поскольку вы успешно выполняете HTTP-запрос GET. Возможно, проблема в вашем бэкэнде. - person Dan; 25.01.2018
comment
В режиме отладки с заголовками, включенными в выборку, выполнение вообще не переходит в бэкэнд, в то время как выполнение идет в бэкэнд без заголовков. Тот же самый backend-метод отлично работает при использовании Angular js в качестве интерфейса. - person Dhaval; 25.01.2018

Основываясь на ваших комментариях, похоже, что основная проблема заключается в том, что вы выполняете запрос CORS из своего реагирующего приложения, которое обслуживается с другого сервера, чем ваш Spring backend. Я не знаю Spring, но добавление HTTP-заголовка Access-Control-Allow-Origin (а также некоторых других заголовков, связанных с CORS) решит проблему. Я не уверен на 100%, почему, когда вы выполняете выборку без заголовков, это работает. Возможно, существует более глубокая проблема конфигурации, или вам необходимо настроить ее, чтобы разрешить запросы с этими заголовками, которые вы передаете (Access-Control-Allow-Headers). Обратите внимание: если вы не планируете разрешать запросы из разных источников в рабочей среде, вы можете добавить эти заголовки, за исключением тех случаев, когда они находятся в разработке.

Вы также можете выполнять выборку в режиме без CORS (передать {mode: 'no-cors'}), но для этого существует множество ограничений, и я сомневаюсь, что вы этого хотите.

person ccnokes    schedule 29.01.2018