我在服务中定义了以下get请求:
createAuthorizationHeader(user, pass) {
let headers: HttpHeaders = new HttpHeaders;
headers = headers.append('Accept', 'application/json, text/plain, */*');
headers = headers.append('Authorization', 'Basic ' + btoa(user + ':' + pass));
headers = headers.append('Content-Type', 'application/json; charset=utf-8');
console.log(headers);
return this.http.get(this._loginUrl, {
headers: headers
});
}
结果是:
OPTIONS https://localhost:8443/delivery/all 401 ()
Failed to load https://localhost:8443/delivery/all: Response for preflight does not have HTTP ok status.
HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false, …}
我也向Postman发出了相同的发帖请求,但是一切正常,因此本地服务器正常工作。
我无法弄清楚我的请求出了什么问题。
答案 0 :(得分:29)
CORS合同要求在飞行前OPTIONS请求上不需要身份验证。看来您的后端需要对OPTIONS请求和GET进行身份验证。
使用Postman访问后端时,您仅发送GET。 浏览器将首先发送一个OPTIONS请求(没有您的身份验证标头),并在响应中查找“ Access-Control-Allow-Origin”标头,该标头与发出请求的页面的来源相匹配。
如果对OPTIONS响应的响应不是2xx,或者不存在标头,或者标头的值与请求页面的原点不匹配,则将得到您遇到的错误,而GET请求将不会。
TLDR;更改后端以在处理登录URL时不需要对OPTIONS方法进行身份验证。
答案 1 :(得分:6)
默认情况下,浏览器不允许用户执行跨域请求。
从Angular为避免此错误,我们可以使用代理配置。
假设angular ui在本地主机:4200上工作,并且它想调用其余的终点网址,例如:https://localhost:8443/delivery/all
以下步骤将解决此问题。
在您的角度应用程序根文件夹中创建一个proxy.config.json文件。 (哪里存在package.json文件) 代理所做的只是简单地在您的前端应用程序运行所在的域+端口上获取浏览器请求,然后将该请求转发到您的后端API服务器。 CORS是浏览器的安全性问题,不适用于进行“后端到后端”通信时(如中间使用代理的情况)。
内容应如下所示。
示例:
{
"/delivery/all/*": {
"target": "https://localhost:8443",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
在我们的应用程序中对/ delivery / all / ...的所有请求都将转发到https://localhost:8443/delivery/all/
注意:changeOrigin属性。当您在后端使用某些虚拟代理(例如使用Apache2配置的代理)时,绝对必须将其设置为true
在运行应用程序时添加代理配置。 Angular支持“ --proxy-config”,您可以在其中提供代理配置文件。 如果使用“ npm start”选项进行测试,则必须添加“ --proxy-config”选项,如下所示。它必须添加到package.json文件中。
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.config.json",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
}
如果直接使用“ ng serve”运行,则已对其进行了如下修改。 “ ng serve --proxy-config proxy.config.json”
可以将Angular应用程序中的HTTP调用更改为此。服务器将自动将请求转发到“ https://localhost:8443/delivery/all”。
this.http.get('https://localhost:8443/delivery/all') .map(res => res.json());
到
this.http.get('/ delivery / all') .map(res => res.json());
这里是更多信息的链接:https://sudhasoftjava.wordpress.com/2018/10/05/proxy-configuration-in-angular/
答案 2 :(得分:0)
@Daryl
我们要做的是为Cors添加自定义配置。然后通过Java服务器中的安全配置启用它。如答案中所述,仅对该服务器启用了直接REST调用。
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
.allowedHeaders("*");
}
};
}
}
这进入了网络安全配置:
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.csrf().disable()
.antMatcher("/**")
.authorizeRequests().and()
.httpBasic()
.and()
.authorizeRequests().anyRequest().authenticated().and().cors();
}
答案 3 :(得分:0)
如果是.Net Web API项目,请编辑web.config并删除下面的标记。
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
答案 4 :(得分:0)
将此行添加到服务器标头配置的末尾
status_header(200);
应该解决问题
答案 5 :(得分:0)
在POST请求之前反应应用程序发送POST请求以检查您的API。
您需要在nginx.conf
中添加此代码段。
location /api/ {
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://localhost:8080;
}