我正在开发的应用程序有问题。 该API位于PHP Symfony 4中,该应用程序由Ionic 4组成。
执行PATCH请求时遇到问题。该请求在POSTMAN以及我的手机上都可以很好地工作 但是在尝试使用浏览器(Google Chrome,Firefox)时,CORS出现问题。
我已经查询,并且我已经了解到PATCH请求首先经过飞行前请求,因此发送了一个请求 使用我的API的OPTIONS方法。
我管理了此方法并返回了代码200,然后按如下所示在index.php文件中允许了正确的标头:
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");
一开始,我遇到了第一个错误,该错误指示该请求未返回代码200,因此我在自己的API中管理了OPTIONS方法。 然后出现以下错误:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
这很奇怪,因为之前没有出现该错误,其他所有请求都可以正常工作。
此外,我尝试使用POSTMAN,并且OPTIONS方法返回正确的标头。
你能帮我吗?
对不起,英语很粗糙。
答案 0 :(得分:1)
对于将来发现此问题的任何人,我都重现了这些确切的症状,并解决了我的问题。简短的回答是,当在客户端指定方法时(例如在 fetch
选项中),PATCH
特别区分大小写,而其他方法则不区分。它需要大写。
尽我所能推断出的解释是,即使 RFC7230 声明方法应该大写,但它们也区分大小写。浏览器通过自动将其中几个大写来解决这个问题,我相信基于 RFC7231 定义了许多常用方法,但没有定义 PATCH。考虑以下从客户端发起的请求。
fetch('https://stackoverflow.com',
{ method: 'post',
body: JSON.stringify({message: 'testing a cors issue'}),
headers: {'Content-Type': 'application/json'}
}
)
至少 Chromium 浏览器的正常行为是自动将 CORS 预检的 Access-Control-Request-Method
标头中的方法大写,而不管我的 JavaScript 在 fetch 调用中使用的大写。
同样,如果方法是 DELETE
,浏览器也会在预检中自动将其大写。
但是,我发现 PATCH
方法(稍后在 RFC5789 中定义)被视为自定义 HTTP 方法,因为它没有强制大写。因此,它区分大小写,这在 CORS 预检期间可以观察到。如果客户端应用程序以小写 patch
指定它,它就是它在 Access-Control-Request-Method 标头中的显示方式,如果它是大写的 PATCH
,它在标头中显示为大写。
当您在 Postman 中选择 PATCH
方法时,它总是大写,这掩盖了问题的根本原因。尽管错误消息与 Access-Control-Allow-Origin
标头有关,但我看到的根本原因是该方法区分大小写。
答案 1 :(得分:0)
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
要解决 CORS 错误,您应该按照以下步骤操作:
proxy.conf.json
在里面写上(复制/粘贴):"/api/*": { "target": "http://myremoteserver/api", "secure": false, "logLevel": "debug" }
打开您的angular.json
文件,并将行proxyConfig":
"proxy.conf.json"
设置为如下所示的 “ serve” :
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "app:build",
proxyConfig": "proxy.conf.json"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
打开您的package.json
并将此行添加到 脚本
数组:
"start": "ng serve --port 8100 --proxy-config proxy.conf.json"
您应得的东西是这样的(见下文):
"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
如果您按照此步骤操作,应该确定
就我而言,它正在工作!!!
最诚挚的问候