通过CORS策略已阻止对“ http:// ....”源“ http:// localhost:4200”处的XMLHttpRequest的访问

时间:2019-09-26 01:56:21

标签: angular angular-material

我正在尝试调用一个因CORS错误而卡住的api。

当我尝试使用“ https:// ....”时,由于服务失败,我遇到了以下错误。

状态码:422。

选项https://xyz/login?username=xxx&password=xxx 422(不可处理的实体) 从源“ https://xyz/login?username=xxx&password=xxx”对“ http://localhost:4200”处XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:无“ Access-Control-Allow-Origin”标头存在于请求的资源上。

当我尝试使用“ http:// ....”时,出现以下错误。

状态码:307临时重定向

从原点“ http://xyz/login?username=xxx&password=xxx”到“ http://localhost:4200”处对XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:预检请求不允许重定向

我尝试添加标题,但添加的标题不会在浏览器中显示。

请求标头如下所示:

显示临时标题 访问控制请求标头:内容类型 访问控制请求方法:POST 来源:http://localhost:4200 推荐人:http://localhost:4200/login 用户代理:Mozilla / 5.0(Macintosh; Intel Mac OS X 10_14_5)AppleWebKit / 537.36(KHTML,例如Gecko)Chrome / 76.0.3809.132 Safari / 537.36

请帮助我解决问题,

我的component.ts看起来像这样

import { FormControl, FormGroup, FormGroupDirective, NgForm, Validators, FormBuilder } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
import { Router, ActivatedRoute } from '@angular/router';
import { first } from 'rxjs/operators';

import { AuthenticationService } from '../services';


@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit{
  loginForm: FormGroup;
   returnUrl: string;
   error = '';

  constructor(
    private formBuilder: FormBuilder,
    private route: ActivatedRoute,
    private router: Router,
    private authenticationService: AuthenticationService) {}

    ngOnInit() {
       this.loginForm = this.formBuilder.group({
           username: ['', [Validators.required , Validators.email]],
           password: ['', [Validators.required]]
       });

       // get return url from route parameters or default to '/'
       this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
   }

   get f() { return this.loginForm.controls; }

    onSubmit() {
        this.authenticationService.login(this.f.username.value, 
            this.f.password.value)
            .pipe(first())
            .subscribe(
                data => {
                    this.router.navigate([this.returnUrl]);
                },
                error => {
                    this.error = error;
                });
    }

}```

and my authentication.service.ts looks like this 

``import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { Http, Headers, RequestOptions, Response, ResponseContentType } from '@angular/http';

@Injectable({ providedIn: 'root' })
export class AuthenticationService {

    constructor(private http: HttpClient) { }

    login(username: string, password: string) {
      const httpOptions = {
       headers: new HttpHeaders({
                    'Content-Type': 'application/json',
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Credentials': 'true'
       })
     };
        return this.http.post(`https://xyz/login 
                         username=xxx&password=xxx, httpOptions)
            .pipe(map(user => {
                if (user) {
                    // some logic
                }
                return user;
            }));
    }
}```

i want to resolve the CORS issue and make successful api call either from client side or from server side. Being fairly new to angular, any details/step by step instructions are appreciated.

Also , i would want to know why added headers wont show on browser. Am i missing anything

3 个答案:

答案 0 :(得分:1)

这个答案也许为时已晚,但是.. 第一期: 如果后端应用程序未返回Access-Control-Allow-Origin,则可以将其添加到安全配置中:

protected void configure(HttpSecurity http) throws Exception {
http.headers()
            .addHeaderWriter(
                    new StaticHeadersWriter("Access-Control-Allow-Origin", "address for your front-end here")
            );
}

答案 1 :(得分:0)

从本地主机开发时,CORS问题很常见。您可以选择一些解决方法:

1)如果您可以控制服务器,请将此标头添加到响应中:

Access-Control-Allow-Origin: *

2)如果您不具有该端点的服务器,请安装this chrome extension。这将添加标题并允许localhost请求。

3)如果您不使用chrome或要在代码中使用代理,请使用this proxy。您的网址最终会是这样的:

https://crossorigin.me/http://xyz/login?username=xxx&password=xxx

答案 2 :(得分:0)

我已将fetch api与cors-anywhere代理一起使用来解决此问题。

onSubmit({ value, valid }: { value: IUserLogin, valid: boolean }) {
  let result;
  const params = {
    "username": value.username,
    "password": value.password
  }

  let url = `https://company.com/login?username=${params.username}&password=${params.password}`;
  const proxyurl = "https://cors-anywhere.herokuapp.com/";
  let req = new Request(proxyurl + url, {
    method: 'POST',
    headers: {

      'Authentication': `Basic ${value.username}:${value.password}`,
      'Content-Type': 'application/json',
      'mode': 'no-cors'

    }
  });

  fetch(req)
    .then(response => response.text())
    .then((contents) => {
      result = JSON.parse(contents);
      console.log(JSON.parse(contents).data)
      if (result.data) {
       // do something
      } else {
       // do something
      }
    })
    .catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))


}