关于上传文件的跨域问题

时间:2022-06-01 16:35:13

在进行新框架开发的过程中,需要自定义页面组件实现脱离表单的文件(图片)上传,考虑过wex5自带的attachmentsimple的自定义写法很难受,就改用了第三方插件webuploader来实现选择文件后调用服务端的上传文件接口实现自动上传。

中间遇到过跨域问题,即服务端所在接口域名与插件包(前端)不在同一域名下,但是由于格式是文件,所以必须采用post传输方式

解决方法:

利用CORS实现POST方式跨域请求数据

CORS全名Cross-Origin Resource Sharing,顾名思义:跨域分享资源,这是W3C制定的跨站资源分享标准。

目前包括IE10+、chrome、safari、FF都提供了XMLHttpRequest对象对该标准的支持,在更老的IE8中则提供了xDomainRequest对象,部分实现了该标准;

在利用XMLHttpRequest对象发POST请求前会发一个options嗅探来确定是否有跨域请求的权限;同时在header头上带上Origin信息来指示来源网站信息,服务器响应时需要带上Access-Control-Allow-Origin头的值是否和Origin信息相匹配。

header("Access-Control-Allow-Origin: http://localhost"); // *为全部域名

CORS的缺点是你必须能控制服务器端的权限,允许你跨域访问

设置CORS实现跨域请求

一、使用php代码实现(写在接口开始位置)

 
    $request_method = $_SERVER['REQUEST_METHOD'];
 
    if ($request_method === 'OPTIONS') {
 
        header('Access-Control-Allow-Origin:'.$origin);
        header('Access-Control-Allow-Credentials:true');
        header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
 
        header('Access-Control-Max-Age:1728000');
        header('Content-Type:text/plain charset=UTF-8');
        header('Content-Length: 0',true);
 
        header('status: 204');
        header('HTTP/1.0 204 No Content');
 
    }
 
    if ($request_method === 'POST') {
 
        header('Access-Control-Allow-Origin:'.$origin);
        header('Access-Control-Allow-Credentials:true');
        header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
 
    }
 
    if ($request_method === 'GET') {
 
        header('Access-Control-Allow-Origin:'.$origin);
        header('Access-Control-Allow-Credentials:true');
        header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
 
    }
 

二、使用nginx配置实现


location / {
 
    set $origin '*';
 
    if ($request_method = 'OPTIONS') {
 
        add_header 'Access-Control-Allow-Origin' $origin;
 
        #
        # Om nom nom cookies
        #
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
 
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
 
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
 
        return 204;
 
    }
 
    if ($request_method = 'POST') {
 
        add_header 'Access-Control-Allow-Origin' $origin;
        add_header 'Access-Control-Allow-Credentials' 'true';
        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';
 
    }
 
    if ($request_method = 'GET') {
 
        add_header 'Access-Control-Allow-Origin' $origin;
        add_header 'Access-Control-Allow-Credentials' 'true';
        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';
 
    }
 
}