我需要从后端Asp Core 2.2下载图像并将其显示在Angular中。
我创建了一个用于以角度显示图像的组件:
HTML代码中的
<img [src]="src$ | async" class="img-fluid img-thumbnail">
在Ts文件中:
@Input() ImagePath: string;
ImageBlob: any;
public src$: Observable<SafeUrl>;
private imageSrc$: BehaviorSubject<string>;
constructor(private downloadService: DownloadService, private domSanitizer: DomSanitizer) {
this.imageSrc$ = new BehaviorSubject(null);
this.src$ = this.imageSrc$.pipe(switchMap(src => this.getImage(this.ImagePath)));
}
ngOnChanges() {
this.imageSrc$.next(this.ImagePath);
}
private createImage(blob: Blob) {
console.log('CREATE_IMAGE');
return this.domSanitizer.bypassSecurityTrustUrl(URL.createObjectURL(blob));
}
private getImage(url: string) {
console.log('GET_IMAGE');
return this.downloadService
.DownloadImage(this.ImagePath)
.pipe(map((blob: Blob) => this.createImage(blob)));
}
}
并在使用中:
DownloadImage(ImageUrl: string): Observable<Blob> {
return this.httpClient.get(ImageUrl, { responseType: 'blob' });
}
现在,当我需要显示图像时,它将在控制台中显示此错误:
CORS策略已阻止从来源“ https://localhost:44372/Uplaod/NewsPictureFolder/NewsMainPicture/903797628068313.jpg”访问“ http://localhost:4200”处的XMLHttpRequest:请求的资源上没有“ Access-Control-Allow-Origin”标头。
获取http://localhost:4200/null 404(未找到)
这是我的拦截器:
@Injectable()
export class RequestInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.includes('/Upload/')) {
console.log('upload')
req = req.clone({ headers: req.headers.set('Access-Control-Allow-Origin', '*') })
return next.handle(req);
}
if (!req.headers.has('Content-Type')) {
console.log('type')
req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
}
req = req.clone({ headers: req.headers.set('Access-Control-Allow-Origin', '*') })
req = req.clone({ headers: req.headers.set('Accept', 'application/json') });
return next.handle(req);
}
}
我不知道问题出在哪里?在前端还是后端?
这是Asp核心中的启动:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithOrigins("http://localhost:4200")
.AllowCredentials()
.Build());
});
问题出在哪里?我该如何解决这个问题?
答案 0 :(得分:2)
ASP.NET Core 2.2不允许组合AllowAnyOrigin
和AllowCredentials
。您需要将AllowAnyOrigin
更改为SetIsOriginAllowed
:
app.UseCors(builder => builder
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed((host) => true)
.AllowCredentials()
);
答案 1 :(得分:2)
尽管其他答案是正确的,但是,如果您要(并且应该)定义允许的特定来源,则应从CORS语句中删除.AllowAnyOrigin()
或SetIsOriginAllowed((host) => true)
,它将与{{ 1}}。
.AllowCredentials()
如果要允许多个Origins,则可以设置一个Origins数组,并将其用作 services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.WithOrigins("http://localhost:4200")
.AllowCredentials()
.Build());
});
中的参数。例如:
.WithOrigins()
此外,请注意所使用的方案-检查是private readonly string[] MyAllowedOrigins = new string[] {
"http://localhost:4200",
"http://localhost:3000"
};
...
.WithOrigins(MyAllowedOrigins)
...
还是http
。
为了完整性,请不要忘记添加例如https
您在其中配置管道的位置,例如app.UseCors("CorsPolicy");
类中的.Configure
方法。
总而言之-尽管在某些情况下允许任何原点都可以,但是您通常希望并且应该明确定义允许的原点。
关于Startup
-这应该是一个表达式,用于评估是否应允许原点,并使其始终返回SetIsOriginAllowed((host) => true)
,这在开发人员中可能是不错的选择。环境,但据我所知,不应在生产中使用。
您可以在MS Docs上找到不错的阅读材料。结帐: