自建API报跨域错误解决

发布于 / 技术 / 0 条评论

最近打算将原来放在别人服务器上的Live2D Api切换到自己的服务器上;配置环境和修改相关配置文件都很简单,但是在API更换之后刷新网页发现曾经正常显示的内容消失了,F12的控制台输出了一个错误:

Access to font at ‘http://test.api.com’ from origin ‘http://test.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

通过阅读可以发现是需要在Header中配置跨域选项才能跨域访问导致的。这个问题出现是因为服务器默认是不允许跨域的——CROS规定的:

跨域资源共享(CORS)标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

跨域资源共享 (Cross-origin resource sharing)

这个协议还规定了除了以下三类以外的所有MIME类型都需要预检请求:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

所以像前文所述的application/json请求就会在正式通信之前先发出一个预检请求,这个预检请求会检查服务器是否配置了Access-Control-Request-Headers: Content-Type,如果没有配置就会跳出前文描述的问题。

如果你在网上搜索的话,多半会遇到这个答案:

location / {  
  add_header Access-Control-Allow-Origin *;
  add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
  add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
} 

但是这个答案对于有些服务器(比如我的)来说是无法工作的,有些服务器配置比较复杂或者location和默认配置并不相同,这就需要你针对自己的服务器进行修改,例如我的服务器所有api都在同一个位置配置,也就是说同一个服务器返回所有结果都是可以跨域的,我可以直接在server层级添加这些内容:

server
{
    listen 80;
	listen 443 ssl http2;
    
    ……
    
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-    With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    ……

}

这样就完成了配置,按住ctrl+F5刷新网页,就能看到API已经正常工作了,我们的看板娘又回来了。

本网站在未特殊说明的情况下采用知识共享署名-非商业性使用-相同方式共享 3.0 协议进行许可。
<-数据丢失->