共享主机触发具有相同域和端口的 CORS
Shared Hosting Triggering CORS with same domain and port
A 过去几天一直在为 CORS 苦苦挣扎,特别是 non-CORS 设置中的预检请求。 我正在通过 axios (domain.com:80) 从 SPA 应用发送请求 到 rest API (domain.com:80/api) 并且它被归类为 CORS 请求。在本地,使用相同的设置,请求很好,不会触发预检 。
在我的研究中,同源请求必须具有:
- 同域
- 相同的子域
- 相同端口
- 相同协议
我认为我的生产环境会检查以上所有内容,但情况恰恰相反。
我的环境按以下方式托管在 shared-host 提供商中:
SPA (Vue) - http://domain:80/company-name/
API (Laravel) - http://domain:80/company-name/api
我已经试过了:
- 在本地克隆环境(工作正常 - 不发送预检请求)
- 启用/禁用Access-Control-Allow-Headers
- 老实说,我什至不知道接下来要尝试什么:|
解决这个问题将使我的应用程序速度提高 100%,这对我来说意义重大。但这根本没有意义。也许我遗漏了一些明显的东西。
可能是我的 shared-hosting 提供商正在做的一些与代理相关的事情。但即使我不知道如何检查。
预检请求示例(来自开发工具中的网络选项卡):
General
Request URL: http:/domain/company-name/api/perfil/3
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: 185.200.153.100:80
Referrer Policy: no-referrer-when-downgrade
Response Headers
Access-Control-Allow-Headers: AUTHORIZATION
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: http:/domain
Access-Control-Max-Age: 25200
Cache-Control: no-cache, private
Connection: close
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Sat, 27 Apr 2019 18:28:40 GMT
Server: Apache
Request Headers
Provisional headers are shown
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Origin: http:/domain
Referer: http:/domain/company-name/perfis
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
请求示例(在预检响应之后):
General
Request URL: http:/domain/company-name/api/perfil/3
Request Method: GET
Status Code: 200 OK
Remote Address: 185.200.153.100:80
Referrer Policy: no-referrer-when-downgrade
Response Headers
Accept-Ranges: bytes
Access-Control-Allow-Origin: http:/domain
Access-Control-Expose-Headers: *
Age: 0
Cache-Control: no-cache, private
Connection: keep-alive
Content-Type: application/json
Date: Sat, 27 Apr 2019 18:28:41 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Origin,Authorization
Via: 1.1 varnish-v4
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-Varnish: 46418125
Request Headers
Accept: application/json, text/plain, /
Authorization: Bearer {token}
Origin: http:/domain
Referer: http:/domain/company-name/perfis
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
域/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(api)($|/) - [L]
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|font.css|css|woff2)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
domain/api/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
如果需要任何其他数据,请随时询问。
也许我遗漏了一些明显的东西。
是的。
在 SPA 中,我正在获取 domain/api
,而实际上 www.domain/api
是正确的。使原点 URL 与请求 URL 匹配,如@sideshowbarker
所述
As far as checking the URLs, the 'domain' part must be exactly the same. So for example 'api.domain.com' and 'www.domain.com' are two different origins. The headers you copied from the Network tab show 'Origin: http:/domain' and 'http:/domain/company-name/api/perfil/3'. So what I am telling you is that the origin of whatever the real 'http:/domain/company-name/api/perfil/3' URL actually is does not exactly match whatever 'Origin: http:/domain' actually is. Either the 'domain' part is not exactly the same, or they are not both 'http' or both 'https', or there is some port number you elided.
A 过去几天一直在为 CORS 苦苦挣扎,特别是 non-CORS 设置中的预检请求。 我正在通过 axios (domain.com:80) 从 SPA 应用发送请求 到 rest API (domain.com:80/api) 并且它被归类为 CORS 请求。在本地,使用相同的设置,请求很好,不会触发预检 。
在我的研究中,同源请求必须具有:
- 同域
- 相同的子域
- 相同端口
- 相同协议
我认为我的生产环境会检查以上所有内容,但情况恰恰相反。
我的环境按以下方式托管在 shared-host 提供商中:
SPA (Vue) - http://domain:80/company-name/
API (Laravel) - http://domain:80/company-name/api
我已经试过了:
- 在本地克隆环境(工作正常 - 不发送预检请求)
- 启用/禁用Access-Control-Allow-Headers
- 老实说,我什至不知道接下来要尝试什么:|
解决这个问题将使我的应用程序速度提高 100%,这对我来说意义重大。但这根本没有意义。也许我遗漏了一些明显的东西。
可能是我的 shared-hosting 提供商正在做的一些与代理相关的事情。但即使我不知道如何检查。
预检请求示例(来自开发工具中的网络选项卡):
General
Request URL: http:/domain/company-name/api/perfil/3
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: 185.200.153.100:80
Referrer Policy: no-referrer-when-downgradeResponse Headers
Access-Control-Allow-Headers: AUTHORIZATION
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: http:/domain
Access-Control-Max-Age: 25200
Cache-Control: no-cache, private
Connection: close
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Sat, 27 Apr 2019 18:28:40 GMT
Server: ApacheRequest Headers
Provisional headers are shown
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Origin: http:/domain
Referer: http:/domain/company-name/perfis
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
请求示例(在预检响应之后):
General
Request URL: http:/domain/company-name/api/perfil/3
Request Method: GET
Status Code: 200 OK
Remote Address: 185.200.153.100:80
Referrer Policy: no-referrer-when-downgradeResponse Headers
Accept-Ranges: bytes
Access-Control-Allow-Origin: http:/domain
Access-Control-Expose-Headers: *
Age: 0
Cache-Control: no-cache, private
Connection: keep-alive
Content-Type: application/json
Date: Sat, 27 Apr 2019 18:28:41 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Origin,Authorization
Via: 1.1 varnish-v4
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-Varnish: 46418125Request Headers
Accept: application/json, text/plain, /
Authorization: Bearer {token}
Origin: http:/domain
Referer: http:/domain/company-name/perfis
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
域/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(api)($|/) - [L]
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|font.css|css|woff2)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
domain/api/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
如果需要任何其他数据,请随时询问。
也许我遗漏了一些明显的东西。
是的。
在 SPA 中,我正在获取 domain/api
,而实际上 www.domain/api
是正确的。使原点 URL 与请求 URL 匹配,如@sideshowbarker
As far as checking the URLs, the 'domain' part must be exactly the same. So for example 'api.domain.com' and 'www.domain.com' are two different origins. The headers you copied from the Network tab show 'Origin: http:/domain' and 'http:/domain/company-name/api/perfil/3'. So what I am telling you is that the origin of whatever the real 'http:/domain/company-name/api/perfil/3' URL actually is does not exactly match whatever 'Origin: http:/domain' actually is. Either the 'domain' part is not exactly the same, or they are not both 'http' or both 'https', or there is some port number you elided.