1

I am working on login page with ReactJs,Spring Boot and rest web services.My Reactjs frontend application is running on port 8080 while my webservice/spring boot application is running on port 9090. I am trying to use the "fetch" method to connect with my backend code, but I am facing error while passing headers in fetch request. If I remove headers property, execution goes into the called backend method. I need to pass Headers in fetch method as it required to access them in web service method.

Please find Snapshot of network requests and responses. Without Headers With headers

Below is my code of React JSX file:

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;
Dhaval
  • 19
  • 1
  • 4
  • What's the error ? – Umesh Jan 25 '18 at 09:12
  • If I am including the header, fetch call is not working. and if I am not using headers It is throwing me "Error : TypeError: Failed to fetch" error. @Umesh – Dhaval Jan 25 '18 at 09:31
  • `method` should be `GET` not `get` I guess. – Umesh Jan 25 '18 at 09:40
  • I changed it with 'GET'. Still facing same issue. – Dhaval Jan 25 '18 at 09:47
  • Fetch requires a Headers object, e.g. var h = new Headers(). See MDN: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch – dannyjolie Jan 25 '18 at 10:21
  • I have also tried that @dannyjolie – Dhaval Jan 25 '18 at 10:31
  • I'm really confused.... your "Without headers" screenshot shows the request failing (presumably client side because the status is "canceled"), but the "With headers" screenshot is working, albeit without the actual headers you included in the request. Can you clarify exactly what's going on? Are the screenshot labels flipped? Also check the Javascript console for errors too. – ccnokes Jan 25 '18 at 22:47
  • @Dhaval, can you check your backend api is working fine .e.g like using postman etc – Umesh Jan 26 '18 at 01:51
  • @Umesh Yes I have checked it with Postman. I am getting appropriate response in that. So backend api is working properly. – Dhaval Jan 29 '18 at 04:35
  • @ccnokes The screenshots labels are proper. I am getting this error in console while using headers : "Fetch API cannot load http://192.168.0.239:9090/ws/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled." – Dhaval Jan 29 '18 at 05:15
  • I also tried this trick and Now I am able to fire request with header successfully but it is browser specific configuration for development. I need it for production environment. https://stackoverflow.com/questions/3102819/disable-same-origin-policy-in-chrome – Dhaval Jan 29 '18 at 05:17

3 Answers3

1
var url = "https://yourUrl";
    var bearer = 'Bearer '+ bearer_token;
    fetch(url, {
    method: 'GET',
    withCredentials: true,
    credentials: 'include',
    headers: {
        'Authorization': bearer,
        'X-FP-API-KEY': 'iphone',
        'Content-Type': 'application/json'}
    }).then((responseJson) => {
        var items = JSON.parse(responseJson._bodyInit);
    })
    .catch(error => this.setState({
    isLoading: false,
    message: 'Something bad happened ' + error
    }));
Pankaj Bhardwaj
  • 1,691
  • 14
  • 35
0

You don't need mode: cors, this is default.

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();
Dan
  • 4,211
  • 4
  • 29
  • 55
  • It's still not working. I have already checked with removing "mode:cors" option. Fetch is not working if I include Headers in my fetch method. @Dan – Dhaval Jan 25 '18 at 09:33
  • Can you see the network request in your dev tools? Any console errors? – Dan Jan 25 '18 at 10:07
  • I have added snapshots of network request and responses both cases (with and without headers) – Dhaval Jan 25 '18 at 10:30
  • With header included it showing me Ok with code 200 but in real the request is not fired in backend side. It will directly catch by "Error" method below the fetch method. – Dhaval Jan 25 '18 at 10:32
  • The problem might not necessarily be related to fetch as you are successfully making a HTTP GET request. Your backend might be the problem. – Dan Jan 25 '18 at 11:08
  • In debug mode, with headers included in fetch, the execution is not at all going to backend while the execution is going to backend without headers. The same backend method is working fine while using Angular js as front end. – Dhaval Jan 25 '18 at 11:31
0

Based on your comments, it sounds like the underlying problem is that you're doing a CORS request from your react app, which is being served from a different server than your spring backend. I don't know Spring, but adding a Access-Control-Allow-Origin HTTP header (as well as some other CORS related headers) will clear up the problem. I'm not 100% sure why when you fetch with no headers, it works. There may be a deeper configuration issue or you need to configure it to allow requests with those headers you're passing (Access-Control-Allow-Headers). Note that if you don't plan to allow cross-origin requests in production you may want to add those headers except when in development.

You can also fetch in no CORS mode (pass {mode: 'no-cors'}), but there's a lot of limitations to that and I doubt that's what you want.

ccnokes
  • 5,909
  • 4
  • 40
  • 49