Jquery+Django 实现 CORS 文件传输

场景描述

遇到这样一个开发场景,服务器A作为一个web server(可以看做master)而服务器B 作为一个运行长时间作业的jobs server(slaver),提供restful API 给服务器A调用,并且接受master的参数运行执行时间较长的脚本。由于脚本存储在slaver上面,且脚本的上传是在web 前端页面完成的,如何处理脚本的上传是一个值得思考的问题。首先想到的是一个非常常规的做法:将脚本首先暂存在master上面,然后在master server 上调用API再次将文件传递到slaver。这个过程过于复杂,其中还涉及到了两次的文件上传的过程,所以弃用。之前搞前端开发的时候做过跨站点资源的访问问题,正好在这个问题上web server 和 jobs server 属于不同的domain,可以尝试使用CORS资源访问的方式实现这个过程。

前端处理过程

首先纯粹的Jquery还没发实现form元素里面的文件上传,还需要一个jquery 的plugin jquery.form.js
然后最简单做法如下:

<form id="formid">
    <input type="file" name="file"/>
    <button type="submit" >submit</button>
</form>
$('#formid').ajaxForm({
    'url':remoteapi // 由于是跨站点文件传输,所以这个地方的url必须要配置成远端server提供的接受文件的API
});

后端处理过程

web server 以及 jobs server 都是采用django开发完成,所以需要研究一下如何在django上面开启CORS功能,保证跨站点的请求能够正常的应答。django里面CORS的实现有三种方案。第一:jsonp 实现,大家都知道这种方式只能够处理get请求,所以直接忽略;第二,添加Access-Control-Allow *** 的各种响应头在response里面,这种方式也是常规的一种方式,至少使用任何一种语言开发后端的程序实现CORS资源访问都可以采用这样的一种方式;第三,使用django 的django-cors-headers 中间件,目前调研来看,在django框架里面,这种方式实现CORS资源访问是一个最佳的实践。
主要说明一下在django框架下方法二以及方法三如何实现CORS。
方法二实现步骤:
step1: view.py 文件中添加响应头,内容如下:

def do_request(request):
    response = HttpResponse()
    # 设置可以进行跨域访问的主机名,这个地方在简单请求时设置为任意主机可访问,但是在复杂请求,有OPTIONS预检请求时,必须设置与请求的域相同。
    response['Access-Control-Allow-Origin'] = 'http://localhost:8000'
    # 设置允许跨域访问的方法,一般是如下三个方法,OPTIONS方法比较重要,因为在较为复杂的跨域请求过程中OPTIONS请求会作为一个预检请求优先发送
    response['Access-Control-Allow-Methods'] = 'POST,GET,OPTIONS'
    # 设置CORS 的相关缓存,在这个时间内如果已经存在OPTIONS请求发送,那么复杂请求就不会每一次都预先发送一个OPTIONS请求,但是如果浏览器本身清除缓存,那么这个字段设置无效
    response['Access-Control-Max-Age'] = 3600
    # 响应首部,一般是在请求头中有Access-Contorl-Request-Headers 的时候在响应的头部中也需要设置。为了避免出错还是与浏览器端观察到的Access-Control-Request-Headers内容一致。
    response['Access-Control-Allow-Headers'] = 'x-csrftoken' 

通过如上的设置,可以成功实现跨域的文件传输。
方法三实现步骤:
step1:settings 文件中添加corsheadersINSTALLED_APPS 中。
step2:settings文件中添加orsheaders.middleware.CorsMiddleware 到MIDDLEWARE 的顶部。
step3: settings 文件中简单设置访问域的白名单,来自名单中的域的请求可以被正常处理。

CORS_ORIGIN_WHITELIST = (
    'localhost:8000',
    '127.0.0.1:8000'
)

然后就可以实现CORS文件传输了,当然上面使用django-cors-headers 中间件只是用到了最简单的配置选项,复杂的配置选项参考https://github.com/ottoyiu/django-cors-headers/

最后远端的接收文件并且存储在远端磁盘代码如下:

uploadfile = request.FILES.get('file',None)# file 与前端表征文件上传的元素的name一致。
        if not uploadfile:
            return HttpResponse('no file upload')
        despath = os.path.join(DIR,uploadfile.name)
        filewriter = open(despath,'wb')
        for chunk in uploadfile.chunks():
            filewriter.write(chunk)
        filewriter.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值