2017-08-04 42 views
1

在我的extjs6項目中,我正在上傳一個文件到我的webapi。 (使用窗體... fileuploadfield)文件成功上傳,它應該返回一個簡單的字符串列表,但即使文件上傳得當,在我的控制器它總是返回FAILURE form.submit。原因...「阻止了原始幀」http://localhost:57007「訪問跨源幀。」extjs form.submit由於「訪問一個跨源幀」而失敗

我相信我在某個地方閱讀,當我做form.submit時,它會創建一些導致交叉原點的框架。

通常我不在乎它是否總是返回失敗,因爲作業仍然完成...但我想返回一些不能工作的東西,如果失敗了。有人能以安全的方式幫助我做到這一點嗎?

PANEL

    xtype: 'form', 
       fileUpload: true, //(1) 
       width: 500, 
       frame: true, 
       title: 'Client Recap Upload Form', 
       bodyPadding: '10 10 10 10', 
       margin: '10px 10px 10px 10px', 
       standardSubmit: false, 
       defaults: { 
        anchor: '100%', 
        allowBlank: false, 
        msgTarget: 'side', 
        labelWidth: 50 
       }, 
       items: [{ 
        xtype: 'fileuploadfield', 
        emptyText: 'Select a file', 
        fieldLabel: 'Filename', 
        name: 'file', 
        buttonText: 'Choose a file' 
       }], 
       buttons: [ 
        { 
         text: 'Upload', 
         listeners: { 
          click: 'onButtonFileUpload' 
         } 
        } 
       ] 

控制器

onUploadClientRecap: function (field, e, options, mid) { 

    var me = this; 

    if (field.up('form').getForm().isValid()) { 
     field.up('form').getForm().submit({ 
      url: ExtApplication4.util.GlobalVar.urlTM_UploadClientRecap + mid, 
      waitMsg: 'Uploading your file...', 
      success: function (form, o) 
      { 
       Ext.Msg.show({ 
        title: 'Result', 
        msg: o.response.responseText,//.result.result, 
        buttons: Ext.Msg.OK, 
        icon: Ext.Msg.INFO 
       }); 
      }, 
      failure: function (form, o) 
      { 
       debugger; 
       Ext.Msg.show({ 
        title: 'Result', 
        msg: 'File Uploaded...', 
        buttons: Ext.Msg.OK, 
        icon: Ext.Msg.INFO 
       }); 
      } 
     }); 
    } 
}, 

WEB API

 [Route("api/tradematch/UploadClientRecap/{mid}")] 
    [HttpPost] 
    public List<string> UploadClientRecap(HttpRequestMessage request, int mid) 
    { 
     HttpContext context = HttpContext.Current; 
     HttpPostedFile postedFile = context.Request.Files["file"]; 

     return _repo.UploadClientRecap(postedFile, mid); 
    } 
在我的WebAPI

我也在我的Application_BeginRequest

 protected void Application_BeginRequest(object sender, EventArgs e) 
    { 
     string[] allowedOrigin = new string[5]; 
     allowedOrigin[0] = "http://localhost:57007"; 
     allowedOrigin[1] = "http://x.com"; 
     allowedOrigin[2] = "https://x.com"; 
     allowedOrigin[3] = "https://www.p.com"; 
     allowedOrigin[4] = "http://www.p.com"; 

     var origin = HttpContext.Current.Request.Headers["Origin"]; 
     if (origin != null && allowedOrigin.Contains(origin)) 
     { 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin); 

      if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
      { 
       HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache"); 
       HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); 
       HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, X-Requested-With"); 
       HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
       HttpContext.Current.Response.End(); 
      } 
     } 
運行此代碼

嘗試新的WebAPI返回重定向

 [Route("api/tradematch/UploadClientRecap/{mid}")] 
    [HttpPost] 
    public HttpResponseMessage UploadClientRecap(HttpRequestMessage request, int mid) 
    { 
     HttpContext context = HttpContext.Current; 
     HttpPostedFile postedFile = context.Request.Files["file"]; 

     var response = Request.CreateResponse(HttpStatusCode.Moved); 
     response.Headers.Location = new Uri("http://www.google.com/" + "&output=crudeOil"); 
     return response; 

     //return _repo.UploadClientRecap(postedFile, mid); 
    } 
+0

你究竟在哪裏提交文件? 一般的解決方案是通過發送適當的http頭來顯式地允許CORS在涉及的域之間傳遞,但是從你的片段中不可能給出任何具體的建議...... – Mastacheata

+0

難道你的前端運行在不同於你的api的端口上嗎?您可以使用反向代理來使它們在同一來源下可用 - 或者像Mastacheata之前說過的那樣啓用CORS,更多位於:https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS – devbnz

+0

@ Mastacheata我剛剛更新了我的代碼,向您展示了webapi。這是否給你你需要的信息? – solarissf

回答

0

文件的上傳(POST請求)是不受CORS;然而,訪問iframe(其上下文當前是跨域起源)的主體當然受制於它,並且是跨域問題可能發生的地方(我已經看過很多次了)。我繞過這個

一種方法是採用類似於這個jQuery插件做的方法:https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads#cross-site-iframe-transport-uploads

總之,在你的上傳處理代碼,您重定向到您的客戶端應用程序,並通沿期望的數據,你希望作爲在查詢字符串中上傳的結果(例如,上傳時間,文件名等)可用。然後,在您的客戶端應用程序中,創建一個簡單的重定向頁面,該頁面將處理傳入的查詢字符串並對其進行適當處理。

的原因,所有的工作原理是iframe的那個內容將來自同一個域被最終擔任該請求,一旦重定向發生:

iframe src = cross-domain url 

=> POST upload 
=> Process upload 
=> Redirect response to same domain as original client app 

iframe src = original requesting client 

正因爲如此,就可以順利閱讀內容通過JS,而不用跨過iframe的跨域策略。

這裏是一個什麼樣的上傳代碼(節點)可能看起來像創建重定向一個非常簡單的例子:

app.post('/api/photo', function(req, res) { 
    if (done == true) { 
     var params = { 
      sometext: "I am some text", 
      success: true, 
      msg: 'The upload was successful', 
      filename: 'Avatar.png' 
     }; 

     res.redirect('http://myapp.com/results.html?data=' + JSON.stringify(params)); 
    } 
}); 

然後,您的重定向文件處理響應:

<html> 
    <head> 
     <meta charset="utf-8"> 
     <title>Cross-Domain Upload Redirect Page</title> 
    </head> 
    <body> 
     <script> 
      // strip off "?data="... 
      var data = window.location.search.slice(6), 
       decodedJSON = decodeURIComponent(data); 
      // set JSON string into innerText and textContent 
      // so Ext.data.Connection can treat it 
      // the same as regular iframe uploads 
      document.body.innerText=document.body.textContent=decodedJSON; 
    </script> 
</body> 

+0

我試圖理解這一點,但我對這一些很新。從你創建重定向的文章開始開始,你在節點中說明了這一點,我該怎麼做?它在我的前端還是在我的webapi?我的前端是一個JavaScript框架EXTJS,並且前端API是c# – solarissf

+0

重定向將發生在正在處理上傳的位置;在這種情況下,在你的應用服務器代碼中。 –

+0

我改變了我的webapi代碼來返回重定向,但我不知道如何實際處理它的前端。我收到錯誤請求的URL代碼未在服務器上找到。很可能是因爲我剛剛完成。你有一個如何處理在extjs或JavaScript重定向的例子嗎? – solarissf

相關問題