Response for preflight is invalid (redirect) in an

2020-07-27 02:41发布

I am using angular4 as the frontend and springboot applicaiton as the backend. The integration methods between the frontend and the BFF(backend for frontend) are RESTful requests.

So the frontend sends out a POST request to the backend endpoints handled by SpringBoot REST controller, and the the backend return a 302 redirect response to frontend.

The problem is that I keep encountering the XMLHttpRequest cannot load https://www.google.ca/. Response for preflight is invalid (redirect) problem.

Somehow i dont think it's the problem of the server(backend), since i use postman to test out the backend, and it indeed go to the redirected website (postman didnt render the redirected website tho, it did receive the website file)

POST request from angular4 frontend

observable function in angular4 Service file

validateData(id, pw, path): Observable<Object>{

    let url:string= "http://localhost:8080/backend";

    let headers = new Headers({'Accepts':'text/plain ; application/json', 'Content-type':'Application/json; charset=utf-8', 'Access-Control-Allow-Origin':'*'});

    let userData = JSON.stringify({username: id, password: pw, resumePath: path});

    let options = new RequestOptions({headers: headers});

    //return response 
    return this.http.post(url, userData ,options).map(res=>res.json());
}

calling observable function in Component file

validateData(id:string, pw:string, path:string){

  return this.loginService.validateData(id, pw, path).subscribe(

          //BFF return an object contains REF //implements interface on response
          response=> {
            console.log(response);
          }, 
          error=> { 
            console.log("error occurs");
            console.log(error);
          },
          ()=> {}
      );

}

Response header code from the springboot application backend

backend Restcontroller

@CrossOrigin(origins = "http://localhost:4200") //enable CORS && temperory origin url
@RequestMapping(value= "/backend", method= RequestMethod.POST, produces= "text/plain")
public ResponseEntity getMockData (@RequestBody Credential credential) {

    System.out.println("username: "+ credential.getUsername()+" password: " +credential.getPassword()+" resumePath:" + credential.getResumePath());

    return this.postAuthCred(credential.getUsername(), credential.getPassword(), credential.getResumePath());
}

backend response headers

private ResponseEntity postAuthCred(String username, String password, String path){

  HttpHeaders responseHeaders = new HttpHeaders();

  String responseBody= "http://www.google.ca";

  responseHeaders.add("Origin", "http://localhost:8080");
  responseHeaders.add("Access-Control-Allow-Origin", "*");
  responseHeaders.add("Accept", "text/plain;application/json");
  responseHeaders.add("Access-Control-Allow-Headers", "Content-Type, Content-Range, Content-Disposition, Content-Description");
  responseHeaders.add("Content-Type", "text/plain");
  responseHeaders.add("Access-Control-Allow-Methods ", "HEAD, GET, POST");
  responseHeaders.add("Access-Control-Max-Age", "1728000");
  responseHeaders.add("Location", "https://www.google.ca/");

  return new ResponseEntity(responseBody, responseHeaders, HttpStatus.FOUND);
}

Screenshots of the network log:

web network screenshot - request details

Any help will be appreciated, Thank you.

1条回答
做自己的国王
2楼-- · 2020-07-27 03:14

If I read this question correctly it appears that you are doing:

  1. Frontend requests resource from backend
  2. Backend responds with redirect to Google
  3. Frontend attempts to fetch request from Google but fails due to CORS

A web site is not allowed to make an XHR request outside of its scope (localhost in your example) unless the target server (Google) explicitly allows it. Chrome does not want to allow your site to make requests against google.com on behalf of the user. You can set the window location (e.g. redirect the browser) but you can't do it from the backend.

It sounds like you are processing some kind of authentication flow in a single page application. One workflow that may work is:

  • Have the server respond to all API requests lacking authentication with 401.
  • Have one endpoint on the server (/login) which responds with the 302 to google
  • On the front-end, listen for a 401 and, if detected, change the window location to /login.
查看更多
登录 后发表回答