I'm creating an API end point to upload files in .net core 2 as follow
[HttpPost("{userId}/files")]
public async Task<IActionResult> AddUserFile([FromRoute]string userId)
{
var file = Request.Form.Files.FirstOrDefault();
var myFile = new MyFiles
{
FilePath = await UploadFile(file), // save the file and return url
UserId = userId,
FileName = Request.Form["fileName"],
Description = Request.Form["description"]
};
// todo save file to database
return Ok(myFile);
}
I tested this end point using Postman and it works as expected.
when tried to call this end point from an Angular application as follow
onAddFile(form: NgForm) {
const formData: FormData = new FormData();
formData.append('', this.selectedFile);
formData.append('fileName', form.value.fileName);
formData.append('description', form.value.description);
formData.append('userId', this.userId);
const headers = new Headers();
headers.append('accept-language', 'en');
headers.append('Content-Type', 'multipart/form-data');
headers.append('Authorization', `Bearer ${token}`);
this.http.post(
`https://localhost:44339/api/admin/users/${this.userId}/files`,
formData,
new RequestOptions({ headers: headers })
).subscribe(result => {
console.log(result);
});
}
I get the following error
:44339/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files:1 POST https://localhost:44339/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files
edit:1 XMLHttpRequest cannot load https://localhost:44339/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files . No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ' http://localhost:4200 ' is therefore not allowed access. The response had HTTP status code 500.
and this is the captured request header from the Angular app
:authority:localhost:44339
:method:POST
:path:/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files
:scheme:https
accept:application/json
accept-encoding:gzip, deflate, br
accept-language:en-US,en;q=0.8,ar;q=0.6
authorization:Bearer eyJhbGciOiJIU.........
content-length:21531
content-type:multipart/form-data;
origin:http://localhost:4200
referer:http://localhost:4200/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/edit
and my request payload
------WebKitFormBoundaryqB4rbqWsrra0gwhi
Content-Disposition: form-data; name=""; filename="2017-08-22_21-56-02.png"
Content-Type: image/png
------WebKitFormBoundaryqB4rbqWsrra0gwhi
Content-Disposition: form-data; name="fileName"
er
------WebKitFormBoundaryqB4rbqWsrra0gwhi
Content-Disposition: form-data; name="description"
df
------WebKitFormBoundaryqB4rbqWsrra0gwhi
Content-Disposition: form-data; name="userId"
c6d15e43-00b9-4eda-bac8-635f6017fec9
------WebKitFormBoundaryqB4rbqWsrra0gwhi--
while trying to figure out the issue I noticed that this happens only if the request content-type
is multipart/form-data
, which I have to use in this case to be able to upload the file.
what am I missing here, am I doing some thing wrong in angular or I missed a configuration in the server side API?
Edit:
cors configuration in startup
app.UseCors(builder =>
builder
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.AllowCredentials()
);
I was able to overcome this issue finally, the fix is to delete the content type from the header
headers.delete('Content-Type');
don't leave it empty this will cause an error
Incorrect Content-Type: , multipart/form-data; boundary
You have to enable the CORS on backend as suggested by A.Tim. Following is how it is done in Java for a Spring based app.
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry corsRegistry) {
corsRegistry.addMapping("/**").allowedMethods("*").allowedHeaders("*").allowedOrigins("*");
}
};
}
I believe you have a typo in Angular's http url:
https://localhost:44339/api/admin/users/ ${this.userId}/files
It should be (note the port)
https://localhost:4200/api/admin/users/ ${this.userId}/files
Or better yet, use a relative url so the host is automatically calculated.
If you're actually runing these 2 apps in localhost make sure the one in port 44339 has CORS configured.
Chrome is throwing this error because you are sending a request to a host in a different port. Note that only for testing purposes you can temporally disable this security measure locally in Chrome, if you have Windows press Win+R and then execute:
chrome --disable-web-security --user-data-dir
(you must first close all Chrome instances, including Postman)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.