首先跨域的需求是必须的,由程序架构所决定。
关于跨域那最先想到的还是jq的ajax的jsonp,可是jsonp只能使用get的方式,图片数据太大有可能就不稳定。最终决定使用formdata封装file对象,使用XMLHttpRequest对象发送请求数据。
为了模拟跨域,分别在本地的两个服务器localhost:80和localhost:8090部署后端和前端的代码
前端代码:
<script> //第一步,从剪贴板获取file对象 document.addEventListener('paste', function(event) { var items = (event.clipboardData && event.clipboardData.items) || []; var file = null; if (items && items.length) { for (var i = 0; i < items.length; i++) { if (items[i].type.indexOf('image') !== -1) { file = items[i].getAsFile(); break; } } } if(!file){ return; } //第二步,实现预览,利用FileReader对象实现将file对象转化为base64位字符串 var reader = new FileReader(); reader.onload = function(e){ // 通过e.target.result取到base64然后上传 // 作为src设到image标签上预览 var img=document.createElement('img'); img.src=e.target.result; img.width=110; img.height=100; document.getElementById("box").appendChild(img); } reader.readAsDataURL(file); //此处的file为上面得到的文件对象 //第三步,实现上传, //【1】使用XMLHttpRequest对象post跨域异步上传文件, //【2】使用formdata对象封装file对象数据 var formdata = new FormData(); formdata.append('file', file); var xhr = new XMLHttpRequest(); xhr.open("POST", "http://192.168.1.115/uploadfile/file.php", true); xhr.onload=function(){ var json=JSON.parse(xhr.responseText); if(json.state==1){ alert('上传成功'); } } xhr.send(formdata); }); </script>html:用以预览图片容器
<div id="box"> </div>php:后端
<?php header("Access-Control-Allow-Origin:*");//接收跨域请求设置 if($_FILES['file']['size']) { $date=date('Ymd'); $path="./upload/".$date.'/'; if(!is_dir($path)){ mkdir($path,0777,true); } $name= $path.uniqid().'.png'; if(copy($_FILES['file']['tmp_name'], "$name")) { $arr['state']=1; $arr['url']=$name; }else{ $arr['state']=222; } }else{ $arr['state']=111; } echo json_encode($arr); exit; ?>知识点详述:
【1】跨域
跨域,指的是从一个域名去请求另外一个域名的资源。即跨域名请求。跨域时,浏览器不能执行其他域名网站的脚本,是由浏览器的同源策略造成的,是浏览器施加的安全限制。跨域的严格一点来说就是只要协议,域名,端口有任何一个的不同,就被当作是跨域。【2】同源策略
同源策略是由 Netscape 公司提出的一个著名的安全策略,所有支持 JavaScript 的浏览器都会使用这个策略所谓同源是指,域名,协议,端口相同。当页面在执行一个脚本时会检查访问的资源是否同源,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。【3】[HTML5] FileReader对象
使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要处理的文件或数据。
FileReader通过异步的方式读取文件内容,结果均是通过事件回调获取,下面是一个读取本地txt文件内容的例子:
var input = document.getElementById("file"); //input file input.onchange = function(){ var file = this.files[0]; if(!!file){ //读取本地文件,以gbk编码方式输出 var reader = new FileReader(); reader.readAsText(file,"gbk"); reader.onload = function(){ //读取完毕后输出结果 console.log(this.result); } } }读取读片文件为base64位字符串
var reader = new FileReader(); reader.onload = function(e){ // 通过e.target.result取到base64然后上传 // 作为src设到image标签上预览 var img=document.createElement('img'); img.src=e.target.result; img.width=110; img.height=100; document.getElementById("box").appendChild(img); } reader.readAsDataURL(file); //此处的file为上面得到的文件对象【3】FormData对象
FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据利用一些键值对来模拟一系列表单控件:即将form中的所有表单元素的name和value组装成一个queryString;异步上传二进制文件。与普通Ajax相比,使用FormData的最大优点:可以异步上传二进制文件。Formdata对象创建
1.你可以自己创建一个FormData对象,然后调用它的append()方法来添加字段
var formData = new FormData(); formData.append("username", "Groucho"); formData.append("accountnum", 123456); //数字123456会被立即转换成字符串 "123456"2.通过HTML表单创建FormData对象
想要构造一个包含Form表单数据的FormData对象,需要在创建FormData对象时指定表单的元素。
var formData = new FormData(someFormElement);3.你还可以在创建一个包含Form表单数据的FormData对象之后和发送请求之前,附加额外的数据到FormData对象里
var formElement = document.querySelector("form"); var formData = new FormData(formElement); var request = new XMLHttpRequest(); request.open("POST", "submitform.php"); formData.append("serialnumber", serialNumber++); request.send(formData);