iView的Upload過程,個人遇到的跨域Cors問題和部分分析和解決的過程
遇到問題:
公司在評估用Vue.js前端分離方法來代替asp,需要將實際項目重寫驗證,原有需求包含圖片上傳的功能,採用的swfupload
方法,在重寫過程中,使用iView的upload組件方法,但在模仿官方的教程時,發現upload的上傳無法達到後端的斷點。
分析問題:
首先,看iView的官網實例
<Upload
ref="upload"
:show-upload-list="false"
:default-file-list="defaultList"
:on-success="handleSuccess"
:format="['jpg','jpeg','png']"
:max-size="2048"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:before-upload="handleBeforeUpload"
multiple
type="drag"
action="//jsonplaceholder.typicode.com/posts/"
style="display: inline-block;width:58px;">
開始時,一股腦copy上去,很多before函數和default跑不通,統統刪掉,只保留最基本的能夠跑通過程的參數
<Upload
ref="upload"
type="drag"
action="http://localhost:2442/api/handler2.ashx"
style="display: inline-block;width:90px;">
http://localhost:2442/api/handler2.ashx 這個是用C#寫的後臺handlerhandler.ashx
public void ProcessRequest(HttpContext context)
{//在這行打上斷點
//context.Response.ContentType = "application/json";
context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
context.Response.AddHeader("Access-Control-Allow-Origin", "*");
context.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type,X-PINGOTHER");
context.Response.AddHeader("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,PATCH,POST,DELETE");
}
然後開始嘗試,用Chrome的F12來查看調試
console:
Failed to load http://localhost:2442/api/handler2.ashx: The 'Access-Control-Allow-Origin' header contains multiple values '*, *, *', but only one is allowed. Origin 'http://localhost:8080' is therefore not allowed access.
百度一下,發現時之前寫axios時存在的同樣的問題,但當時在C#代碼里加了Header,就能通過,後面的就直接用的axios處理的代碼,應該不會存在相同跨域的問題。
再查看F12下的NetWork (status:200 只代表響應成功,不代表匹配返回頭成功)
再對比之前axios的network
發現 Request Method 不同,再百度一下,查找cors的相關知識,瞭解非簡單跨域是先發送options,後再POST。
然後,猜測可能是IIS的鍋,用node.js謝了一個簡單的服務
var http = require("http");
http.createServer(function (request , response) {
//設置請求頭
response.setHeader("Access-Control-Allow-Origin","*");
response.writeHead(200,{"Content-Type":"text/plain"});
if(request.method == 'OPTIONS'){
console.log('current method is OPTIONS');
}else if(request.method == 'POST'){
console.log('current mehtod is POST');
}
response.end("Hello World!\n");
}).listen(8888);
console.log('server running at http://127.0.0.1:8888/');
修改Upload的actionaction="http://127.0.0.1:8888"
得到結論:
1.非簡單跨域確實是先options,後post的
2.確實可能IIS存在問題(至少node.js能跑通)
修改web.config的system.webServer
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
發現通過預檢(preflight)
後續思考:
爲什麼之前axios通信時,在handler裏能過通過跨域,而upload通信卻不行?
個人理解:非簡單跨域請求的第一個options不會進入handler進行處理(雖然第一個請求是指向handler2),而是進入項目
配置中,在項目配置中進行檢查,而Header也是根據配置項進行返回。返回後才能進行後續的post請求,進入handler進行處理。
這也是第一次沒有進入斷點的原因。