Reputation: 91
I have a problem with the application I’m developing. The API is in PHP Symfony 4 and the application is made with Ionic 4.
I have a problem when doing PATCH requests. The request works very well on POSTMAN, as well as on my phone but I have problems with CORS when trying on browser (Google Chrome, Firefox).
I have inquired and I have understood that a PATCH request first goes through a pre-flight request and therefore sends a request with the OPTIONS method to my API.
I managed this method and returned a code 200 then I allowed the correct headers in my index.php file as follows:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header("Access-Control-Allow-Methods: GET, HEAD, PATCH, OPTIONS, POST, PUT");
At the beginning, I had a first error which indicated that the request did not return code 200, so I managed the OPTIONS method in my API. Then I have the following error:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
This is strange because the error there did not appear before, and all the other requests work.
In addition, I tried with POSTMAN and the OPTIONS method returns the correct headers.
Can you help me?
Sorry about the rough English.
Upvotes: 2
Views: 4482
Reputation: 4004
For anyone who finds this in this future, I've reproduced these exact symptoms, and solved my issue. The short answer is that when the method is specified on the client-side (e.g. in the fetch
options), PATCH
specifically is case-sensitive while other methods are not. It needs to be capitalized.
The explanation, to the best I've been able to deduce, is that even though the RFC7230 states that methods should be uppercase, they are also case-sensitive. The browsers smooth over this by automatically capitalizing several of them, I believe based on RFC7231 which defines many of the common methods, but does not define PATCH. Consider the following request initiated from the client side.
fetch('https://stackoverflow.com',
{ method: 'post',
body: JSON.stringify({message: 'testing a cors issue'}),
headers: {'Content-Type': 'application/json'}
}
)
The normal behavior for at least a Chromium browser is to automatically capitalize the method in the Access-Control-Request-Method
header of the CORS preflight, regardless of the capitalization my JavaScript uses in the fetch call.
Likewise, if the method is DELETE
, the browser will also automatically capitalize it in the preflight.
However, I found that the PATCH
method (defined later in RFC5789) is treated like a custom HTTP method, in that it is not forcibly capitalized. It is therefore case-sensitive, which is observable during CORS preflights. If the client app specifies it in lowercase patch
, that's how it appears in the Access-Control-Request-Method header, and if it's capitalized PATCH
it appears capitalized in the header.
When you select the PATCH
method within Postman, it's always capitalized, which masks the root cause of the issue. Even though the error message is in regard to the Access-Control-Allow-Origin
header, the root cause that I've seen is the method's case-sensitivity.
Upvotes: 10
Reputation: 275
Environement info-
ionic (Ionic CLI) : 4.0.0
Ionic Framework : @ionic/angular 4.0.0
@angular-devkit/build-angular : 0.8.6
@angular-devkit/schematics : 0.8.6
@angular/cli : 6.2.6
@ionic/angular-toolkit : 1.1.0
For fixing CORS error you should follow this steps:
proxy.conf.json
write this(copy/paste) inside: "/api/*": { "target": "http://myremoteserver/api", "secure": false, "logLevel": "debug" }
Open your angular.json
file and set the line proxyConfig":
"proxy.conf.json"
as you can see below into "serve":
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "app:build",
proxyConfig": "proxy.conf.json"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
Open your package.json
and add this line into the script
array :
"start": "ng serve --port 8100 --proxy-config proxy.conf.json"
you shold get something like this (see below) :
"scripts": {
"ng": "ng",
"start": "ng serve --port 8100 --proxy-config proxy.conf.json",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
}
npm run start
If you followed this steps it's should be OK
For my part it's working !!!
Best regards
Upvotes: 0