gpt4 book ai didi

angular - 如何更正 Angular 为 11 的 Spring Boot 中与 Cors Origin 相关的问题?

转载 作者:行者123 更新时间:2023-12-04 07:56:58 26 4
gpt4 key购买 nike

我在 Spring boot 和 Angular 中开发的 API 有问题。当我尝试用图像录制新的表演时,我总是遇到与 Cors 跨源 header 相关的相同错误。

这是我的 Controller 和用于创建 Prestation 的方法

@RestController
@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
@RequestMapping("/prestations")
public class PrestationController {

private byte[] bytes;
@Autowired
IPrestationService prestationService;
@Autowired
PrestationRepository prestationRepository;
@Autowired
ServletContext context;


@PostMapping
public ResponseEntity<MessageResponse> savePrestaWithImage(@RequestParam("file") MultipartFile file, @RequestParam("prestation")String prestation)
throws JsonParseException, JsonMappingException, Exception {
Prestation presta = new ObjectMapper().readValue(prestation, Prestation.class);
boolean isExist = new File(context.getRealPath("/Images/")).exists();
if(!isExist){
new File(context.getRealPath("/Images/")).mkdir();
System.out.println("dossier créer");
}
String filename = file.getOriginalFilename(); // je recupere le nom de l'image
String newFileName = FilenameUtils.getBaseName(filename)+"."+FilenameUtils.getExtension(filename);
File serverFile = new File(context.getRealPath("/Images/"+File.separator+newFileName));
try {
System.out.println("Image");
FileUtils.writeByteArrayToFile(serverFile, file.getBytes());
}catch (Exception e){
e.printStackTrace();
}
presta.setPhoto(newFileName);
Prestation prestation1 = prestationRepository.save(presta);
if(prestation1 != null){
return new ResponseEntity<MessageResponse>(new MessageResponse(""), HttpStatus.OK);
}else {
return new ResponseEntity<MessageResponse>(new MessageResponse("Prestation not saved"), HttpStatus.BAD_REQUEST);
}

}

这是我的 Angular 服务

savePrestation(prestation: Prestation): Observable<Prestation> {
const httpOptions = {
headers: new HttpHeaders({
'Content-type ': 'application/json',
'Acces-Control-Allow-Origin': '/*'
})
}
return this.http.post<Prestation>(this.SAVE_PRESTA, prestation, httpOptions).pipe(
tap(_ => this.log(`save prestation with id = ${prestation.id}`)),
catchError(this.handleError<any>('addPresta'))
);
}

这是我的 Angular 方法 savePresta

savePresta() {
const uploadData = new FormData();
uploadData.append('imageFile', this.selectedFile, this.selectedFile.name);
this.selectedFile.imageName = this.selectedFile.name;

this.http.post(this.SAVE_PRESTA + '/upload', uploadData, { observe: 'response' }).subscribe(
(response) => {
if (response.status == 200) {
this.service.savePrestation(this.prestation).subscribe(
(prestation) => {
this.prestation = prestation;
this.goBack();
});
console.log('image uploaded successfull');
} else {
console.log('image not uploaded sucessfull')
}
});
}

还是一样的错误

Access to XMLHttpRequest at 'http://localhost:8080/prestations' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
POST http://localhost:8080/prestations net::ERR_FAILED

ERROR HttpErrorResponse headers: HttpHeaders status: 0 statusText: "Unknown Error" url:"http://localhost:8080/prestations", ok: false …

help me please that days that I block the top I tried everything but nothing helped

最佳答案

这是一个 CORS 问题,与安全问题有关。

问题

假设您的前端托管在 xxx.com 上,后端托管在 yyy.com 上。

从浏览器的 Angular 来看,您连接到 xxx.com 但向 yyy.com 发出请求,这很奇怪。如果 yyy.com 没有明确授权从 xxx.com 发送请求,浏览器将阻止该请求。

现在,浏览器如何知道 yyy.com 授权来自 xxx.com 的请求?带有飞行前请求。浏览器执行飞行前请求并期望在响应中找到一些与 CORS 相关的 HTTP header 。看 ?这是错误消息中的内容:Response to preflight request doesn't pass access control check

这是此类 HTTP header 的示例:

Access-Control-Allow-Origin: http://toto.example
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400

在这里,localhost:4200localhost:8080 被认为是 2 个不同的来源

你能做什么?

您有 2 个解决方案:创建代理或设置正确的 HTTP header

创建代理

假设您在 zzz.com 上创建了一个代理。您的浏览器已连接到 zzz.com,所有后端调用都对 zzz.com 进行。从您的浏览器 Angular 来看,不再有跨源资源共享。

但是,zzz.com 必须将前端请求重定向到 xxx.com,将后端请求重定向到 yyy.com。如果您决定所有后端请求都以类似 /api 的内容开头,则可以轻松完成此操作。这将允许您编写一个简单的正则表达式:

  • /api => 后端开始
  • else => 前端

幸运的是,在开发环境中,Angular 提供了一个内置的解决方案。你可以看看Proxying to a backend server它仅包括使用指向文件的 --proxy-config 选项启动 Angular 应用程序,例如:

{
"/api": {
"target": "http://localhost:8080",
"secure": false
}
}

(在这里,我们假设您所有的后端端点都以 /api 开头)

HTTP header

这个答案提供了一些 Angular conf 的解决方案:How to resolve the CORS issue using proxy in angular

从不曾经使用Access-Control-Allow-Origin: *

如果您想轻松修改 HTTP header 以进行测试,您可以安装 Chrome 扩展程序 modHeader

注意:当您投入生产时,您会遇到这个问题,因此解决方案的选择必须由您在生产中所需的解决方案驱动。

关于angular - 如何更正 Angular 为 11 的 Spring Boot 中与 Cors Origin 相关的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66651961/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com