访问“http://....”源“http://localhost:4200”的 XMLHttpRequest 已被 CORS 策略阻止
Posted
技术标签:
【中文标题】访问“http://....”源“http://localhost:4200”的 XMLHttpRequest 已被 CORS 策略阻止【英文标题】:Access to XMLHttpRequest at "http://...." origin 'http://localhost:4200' has been blocked by CORS policy 【发布时间】:2020-01-26 05:53:58 【问题描述】:我正在尝试调用一个我遇到 CORS 错误的 api。
当我尝试使用 "https://...." 时,我遇到了以下错误,服务失败。
状态码:422。
选项https://xyz/login?username=xxx&password=xxx 422(无法处理的实体) 从源“http://localhost:4200”访问“https://xyz/login?username=xxx&password=xxx”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源。
当我尝试使用“http://....”时,我收到以下错误。
状态码:307 临时重定向
从源“http://localhost:4200”访问位于“http://xyz/login?username=xxx&password=xxx”的 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, like 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
【问题讨论】:
Angular 4.3 HttpClient doesn't send Authorization header的可能重复 这个问题是因为后端CORS配置,在后端代码中添加CORS允许'*' 【参考方案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")
);
【讨论】:
【参考方案2】:我已经使用 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?"))
【讨论】:
一段时间后,herokuapp 会阻止我们的域几分钟(当他们不得不刷新限制计数时),因为他们的点击次数有限。通过托管我自己的代理解决了这个问题。 节省了我的时间,谢谢伙计,我将使用自己的代理。这有效【参考方案3】:从 localhost 开发时,CORS 问题很常见。你有一些选择来解决这个问题:
1) 如果您可以控制您的服务器,请将此标头添加到响应中:
Access-Control-Allow-Origin: *
2) 如果您不拥有带有端点的服务器,请安装this chrome extension。这将添加标头并允许本地主机请求。
3) 如果您不使用 chrome,或者如果您想在代码中使用代理,请使用 this proxy。你的网址最终会是这样的:
https://crossorigin.me/http://xyz/login?username=xxx&password=xxx
【讨论】:
使用这个扩展会不会在部署应用时遇到问题?以上是关于访问“http://....”源“http://localhost:4200”的 XMLHttpRequest 已被 CORS 策略阻止的主要内容,如果未能解决你的问题,请参考以下文章
GWT 阻止源为“http://localhost”的框架访问跨域框架
CORS 策略已阻止从源访问“http://localhost...”处的 XMLHttpRequest:
请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问源“http://localhost”