阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      前端向又拍云上传文件,报错Refused to set unsafe header "Date"

      遇到的问题

      调用又拍云接口的时遇到了一个问题记录;

      在每次调用又拍云接口时,先通过签名认证拿到了签名和Date。

      如果请求头不加 Date 又拍云服务器返回数据如下

      {
          "msg":"need date header",
          "code":40100001,
          "id":"XXXXX"
      }
      

      接口需要Date参数;

      给请求头加上Date参数,浏览器会报错。

      Refused to set unsafe header "Date"
      

      在Chrome中使用REST API 发送请求时,在请求的HTTP Header中添加Date参数,Chrome会提示:Refused to set unsafe header “Date” ,因为Chrome按照W3C的要求执行,Date为不安全字符(详情查看http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method)

      匹配以下不安全字符时,将被终止

      w3c规定,当请求的header匹配以下不安全字符时,将被终止

      Accept-Charset
      Accept-Encoding
      Connection
      Content-Length
      Cookie
      Cookie2
      Content-Transfer-Encoding
      Date
      Expect
      Host
      Keep-Alive
      Referer
      TE
      Trailer
      Transfer-Encoding
      Upgrade
      User-Agent
      Via
      

      Date为默认的字符,不能自定义传入,所以请求被拒绝了。

      而又拍云又需要在请求头上加上Date,所以导致了又拍云接口不能顺利调用。

      我给upyun发工单后,发现他们也是有对应的解决方案的

      解决方案

      前端跨域上传的时候,可以使用 X-Date 参数替换 Date 参数。

      另外如果您使用的 FORM API 方式进行上传,签名和 HTTP 请求过程中可以不使用 Date 参数。

      演示方案

      HTML 文件

      hash文件和jquery就不贴了;

      <!DOCTYPE html>
      <head>
      <meta charset="utf-8">
      <script src="hash.js"></script>
      <script src="jquery-1.9.0.min.js"></script>
      <script>
      $(function(){$("body").html("<div id='fileinput'></div><div id='fileinfo'></div>");$("#fileinput").html("<input id='fileupload' type='file' name='file' onchange='ufload(this)'/><br/><br/>");});
      function ufload(obj) {
      		var bucketname="xxx"; //服务名
      		var username="xxx";	  //操作员账号
      		var password="xxx";     //操作员密码
      		var save_key="/{filename}{.suffix}";
      		var url="http://v0.api.upyun.com/"+bucketname;
      		var file=$(obj).get(0).files[0];
      		var fileinfo=document.getElementById("fileinfo");
      		var policy=btoa(JSON.stringify({"bucket": bucketname, "save-key": save_key, "expiration": parseInt(Date.parse(new Date())+3600)}));
      		var signature="UPYUN "+username+":"+b64hamcsha1(HexMD5.MD5(password).toString(HexMD5.enc.Hex), "POST&/"+bucketname+"&"+policy);
      		fileinfo.innerHTML="文件名称: "+file.name+"<br/>"+"文件大小: "+file.size+"<br/>"+"文件类型: "+file.type+"<br/><br/>"+
      		"<div id='progress' style='width:300px;height:14px;border:1px solid #ddd;padding-top:0px;border-radius:4px;display:none'><div id='bar' style='float:left;background-color:#62BFFF; width:0%; height:14px; border-radius:3px;'></div><div id='percent' style='float:left;width:0px;display:inline-block; top:0px;font-size:10px;'></div>";
      		var xhrOnProgress=function(fun){
      			xhrOnProgress.onprogress=fun;
      			return function(){
      				var xhr=$.ajaxSettings.xhr();
      				if (typeof xhrOnProgress.onprogress!=='function'){
      					return xhr;
      				}
      				if (xhrOnProgress.onprogress&&xhr.upload){
      					xhr.upload.onprogress=xhrOnProgress.onprogress;
      				}
      				return xhr;
      			}
      		}
      		var formData=new FormData();
      		formData.append("file",file);
      		formData.append("policy",policy);
      		formData.append("authorization",signature);
      		$.ajax({
      			url:url,
      			type:"POST",
      			data:formData,
      			contentType:false,
      			processData:false,
      			xhr:xhrOnProgress(function(e){ 
      				var percent=Math.round(e.loaded*100/e.total);
      				$("#progress").show();
      				$("#percent").text(percent+"%");
      				$("#bar").width(percent+'%');
      			}),
      			success:function(data, textStatus,xhr){
      				$("#progress").hide();
      				fileinfo.innerHTML+="上传成功!<br/><br/>";
      				for (var key in JSON.parse(data)){
      				fileinfo.innerHTML+=key+": "+JSON.parse(data)[key]+"<br/>";
      			  }
      
      			},
      			error:function(xhr){
      				$("#progress").hide();
      				fileinfo.innerHTML+="上传失败!<br/><br/>";
      				for (var key in JSON.parse(xhr.responseText)){
      				fileinfo.innerHTML+=key+": "+JSON.parse(xhr.responseText)[key]+"<br/>";
      			  }
      			}
              });
      }
      </script>
      </head>
      <body></body>
      </html>
      
      目录
      目录