预检的响应在angular2 / 4

时间:2017-07-24 15:06:26

标签: angular rest redirect spring-boot rxjs

我使用angular4作为前端,使用springboot应用作为后端。前端和BFF(前端的后端)之间的集成方法是RESTful请求。

因此,前端向SpringBoot REST控制器处理的后端端点发出POST请求,后端向前端返回302重定向响应。

问题是我一直遇到 XMLHttpRequest无法加载https://www.google.ca/。预检的响应无效(重定向) 问题。

不知怎的,我不认为它是服务器(后端)的问题,因为我使用邮递员测试后端,它确实去了重定向的网站(邮递员没有渲染重定向的网站,它做了收到网站文件)

来自angular4前端的POST请求

angular4服务文件中的

可观察函数

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());
}

在组件文件中调用observable函数

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);
          },
          ()=> {}
      );

}

springboot应用程序后端的响应头代码

后端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());
}

后端响应标头

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);
}

网络日志的屏幕截图:

web network screenshot - request details

任何帮助将不胜感激,谢谢。

1 个答案:

答案 0 :(得分:0)

如果我正确地阅读了这个问题,你似乎正在做:

  1. 前端从后端请求资源
  2. 后端通过重定向回复Google
  3. 前端尝试从Google获取请求但由于CORS而失败
  4. 除非目标服务器(Google)明确允许,否则不允许网站在其范围之外(示例中为localhost)发出XHR请求。 Chrome不希望您的网站代表用户针对google.com提出请求。您可以设置窗口位置(例如重定向浏览器),但不能从后端执行此操作。

    听起来您正在单页应用程序中处理某种身份验证流程。可能有效的一个工作流程是:

    • 让服务器响应所有缺少401身份验证的API请求。
    • 在服务器(/ login)上有一个端点响应302 to google
    • 在前端,侦听401,如果检测到,则将窗口位置更改为/ login。