练习:通过AJAX跨域上传文件

这里包含两个知识点,通过AJAX来上传文件+跨域问题

跨域问题的解决方案:W3C标准CORS(Cross-Origin Resource Sharing)规范,在服务器端使用filter来设置response头的跨域相关属性。

Chrome在发起AJAX请求时,会检查请求是否跨域,如果是,它会先发起一个OPTIONS类型的请求来向服务器查询跨域权限。比如你的AJAX是一个跨域的POST请求,那么在真正向服务器发送该POST请求之前,会先触发一个OPTIONS请求,该请求的头里包含以下属性:

Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST

  

如果服务器返回的response头里包含类似这样的信息,那么就表示服务器接受这个跨域请求:

Allow:GET, HEAD, POST, TRACE, OPTIONS

  

然后真正的POST跨域请求才会被发送。

服务器端代码使用的是第三方的cors-filter-1.3.2.jar,java-property-utils-1.6.jar

通过AJAX来发起上传文件的POST请求

HTML代码

<form enctype="multipart/form-data" >
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

JS代码以jQuery为例,在调用$.ajax()方法时,传入一个FormData对象,并且将contentType和processData设为false

var formData = new FormData($('form')[0]);
$.ajax({
    url: '你的跨域URL',  //Server script to process data
    type: 'POST',
    //Ajax events
    //beforeSend: beforeSendHandler,
    //success: completeHandler,
    //error: errorHandler,
    // Form data
    data: formData,
    //Options to tell jQuery not to process data or worry about content-type.
    cache: false,
    contentType: false,
    processData: false
});

测试在Chrome 35和Firefox 30上通过。

后续问题(待更新):1. IE8不支持FormData,如何实现? 2. 服务器端代码替换成Apache标准的代码。3. 跨域携带cookie(设置withCredentials?)4. 服务器端开放所有对所有域的AJAX请求,安全性问题?

相关推荐