请求中不存在“Access-Control-Allow-Origin”标头
Posted
技术标签:
【中文标题】请求中不存在“Access-Control-Allow-Origin”标头【英文标题】:No 'Access-Control-Allow-Origin' header present in request 【发布时间】:2019-03-08 17:36:56 【问题描述】:我已经阅读了很多关于此的主题,但它仍然不起作用,我正在失去理智。
我有一个带有 Spring Api 的 Angular6 应用程序,当我调用它时我一直有这个错误:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
但我觉得我什么都做了:
这是我对 Angular App 中 api 的调用:
getGamesFromServer()
const httpOptions =
headers: new HttpHeaders(
'Access-Control-Allow-Origin':'*'
)
;
this.httpClient
.get<any[]>('http://localhost:8080/api/rest/v1/game/progress', httpOptions)
.subscribe(
(response) =>
console.log(response);
this.games = response;
console.log(this.games);
this.emitGameSubject();
,
(error) =>
console.log('Erreur ! : ' + error);
);
这里是调用的java方法:
@RequestMapping(method = GET, value = "/progress")
@ResponseBody
public Response findAllAndProgress()
return Response.status(Response.Status.OK)
.entity(gameService.findAllAndProgress())
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
.build();
我还启动了 chrome 并激活了 --disable-web-security 选项,我还下载了一个 chrome 扩展以允许 CORS 请求,但它没有用
【问题讨论】:
您的 Angular 应用程序从哪里运行,端口 4200? 是的,角度应用程序端口 4200 和 java api 8080 你不需要在 Angular 前端添加Access-Control-Allow-Origin
,这只是需要回答这个问题的 API
【参考方案1】:
在 java 上,在您的 api 上添加以下这一行
@CrossOrigin(origins = "http://localhost:4200")
您还可以从 Angular 端代理您的请求。 Angular 为您提供可以代理请求的内置服务器。按照以下步骤:
-
在项目的根目录中添加 proxy.config.json 文件。
在 proxy.config.json 文件中添加以下代码
“/api/”: “目标”: “主机”:“本地主机”, “协议”:“http:”, “端口”:8080 , “安全”:错误, “changeOrigin”:是的, “日志级别”:“调试”
在 package.json 中找到脚本下的 start 并替换为以下内容:
ng 服务 --proxy-config proxy.config.json
使用以下代码编辑您的角度代码:
this.httpClient .get('/api/rest/v1/game/progress', httpOptions) 。订阅( (响应)=> 控制台日志(响应); this.games = 响应; console.log(this.games); this.emitGameSubject(); , (错误)=> console.log('Erreur ! : ' + 错误); );
【讨论】:
【参考方案2】:我假设这是因为 Angular 应用程序在开发模式下运行,并且从与 Spring webapp 不同的端口提供服务。您可以使用指定给应用启动 (ng serve --proxy-config proxy.conf.json
) 的 proxy.conf.json
文件来解决此问题,也可以将 @CrossOrigin(origins = "*")
添加到 Spring 控制器中作为快速而肮脏(但不太适合生产)的解决方案。
以下代码不起作用的原因:
@RequestMapping(method = GET, value = "/progress")
@ResponseBody
public Response findAllAndProgress()
return Response.status(Response.Status.OK)
.entity(gameService.findAllAndProgress())
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
.build();
是因为该方法实际上从未被执行以添加标题。跨域请求在发出实际请求(在您的情况下为 HTTP GET)之前启动预检请求(HTTP OPTION)。正是那个预检请求失败了。这就是为什么将注解添加到控制器将解决问题的原因。
【讨论】:
好的,我明白了。我尝试添加注释,但是当我将 spring-web 添加到我的 pom 时它不起作用。我认为我与 spring-web 的版本不兼容【参考方案3】:在根目录下创建 proxy.conf.json 文件,包含下一个内容:
"/api/*":
"target": "http://localhost:8080",
"secure": false
并且在 package.json 文件中,您必须将启动脚本从 ng serve
更改为 ng serve --proxy-config proxy.conf.json
有关代理配置的更多详细信息:Link
【讨论】:
无效...根目录是src还是真正的根目录? 我认为您需要在target
和secure
之后添加"changeOrigin": true
对以上是关于请求中不存在“Access-Control-Allow-Origin”标头的主要内容,如果未能解决你的问题,请参考以下文章
请求的资源在 Salesforce 中不存在 [错误]。 Salesforce 出了啥问题?
使用 multer 文件输入的 axios 请求中不存在所需的请求部分“文件”
Node.Js 错误“请求中不存在 'Access-Control-Allow-Origin' 标头”