[英]How to correct a problem related to the Cors Origin in spring boot with angular 11?
我在 Spring 启动和 Angular 中开发的 API 有问题。 当我尝试用图像录制新的表演时,我总是有与 Cors 跨源标题相关联的相同错误。
这是我的 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
上。
从浏览器的角度来看,您连接到xxx.com
但向yyy.com
发出请求,这很奇怪。 如果yyy.com
没有明确授权从xxx.com
发送请求,浏览器将阻止该请求。
现在,浏览器如何知道yyy.com
授权来自xxx.com
的请求? 有飞行前的请求。 浏览器执行飞行前请求并期望在响应中找到一些与 CORS 相关的 HTTP 标头。 看? 这是错误消息中所写的内容: Response to preflight request doesn't pass access control check
以下是此类 HTTP 标头的示例:
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:4200
和localhost:8080
被认为是 2 个不同的来源
你能做什么?
您有 2 个解决方案:创建代理或设置正确的 HTTP 标头
创建代理
假设您在zzz.com
上创建代理。 您的浏览器已连接到zzz.com
,并且所有后端调用都对zzz.com
。 从您的浏览器的角度来看,没有更多的跨源资源共享。
但是, zzz.com
必须将前端请求重定向到xxx.com
并将后端请求重定向到yyy.com
。 如果您决定所有后端请求都以/api
之类的内容开头,则可以轻松完成此操作。 这将允许您编写一个简单的正则表达式:
/api
=> 后端开头幸运的是,在开发环境中,Angular 为此提供了内置解决方案。 您可以查看Proxying to a backend server它仅包括启动 angular 应用程序,并使用--proxy-config
选项指向一个文件,例如:
{
"/api": {
"target": "http://localhost:8080",
"secure": false
}
}
(在这里,我们假设您所有的后端端点都以/api
开头)
HTTP 接头
此答案提供了一些 Angular conf 的解决方案: How to resolve the CORS issue using proxy in angular
永远不要使用Access-Control-Allow-Origin: *
如果您想轻松修改 HTTP Headers 以进行测试,您可以安装 Chrome 扩展modHeader
注意:当您将 go 投入生产时,您将遇到这个问题,因此解决方案的选择必须由您在生产中所需的解决方案驱动。
在处理 cors 时,我使用非常简单的解决方案来开发 Spring Web 服务:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// other configs ...
http.cors();
// other configs ...
@CrossOrigin
@RestController
public class EventController extends BaseController {
}
但是,如果将 @CrossOrigin 移动到 BaseController 可以工作,也许可以简化(我没有检查过)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.