2009-02-03 20 views
10

Tôi có tập lệnh tải lên tệp Flex sử dụng URLRequest để tải tệp lên máy chủ. Tôi muốn thêm hỗ trợ cho http xác thực (mật khẩu bảo vệ thư mục trên máy chủ), nhưng tôi không biết làm thế nào để thực hiện điều này - Tôi giả sử tôi cần phải mở rộng lớp bằng cách nào đó, nhưng làm thế nào để tôi là một chút bị mất.Flex 3 - cách hỗ trợ URL xác thực HTTPRequest?

Tôi đã cố sửa đổi những điều sau (thay thế HTTPService bằng URLRequest), nhưng điều đó không hiệu quả.

private function authAndSend(service:HTTPService):void{   
    var encoder:Base64Encoder = new Base64Encoder();   
    encoder.encode("someusername:somepassword");   
    service.headers = {Authorization:"Basic " + encoder.toString()}; 
    service.send(); 
} 

Tôi nên chỉ ra rằng tôi không hiểu biết khi nói đến ActionScript/Flex, mặc dù tôi đã quản lý thành công sửa đổi kịch bản tải lên một chút.

[Chỉnh sửa] - đây là một bản cập nhật về sự tiến bộ của tôi, dựa trên câu trả lời dưới đây, mặc dù tôi vẫn không thể có được điều này để làm việc:

Cảm ơn bạn đã hỗ trợ của bạn. Tôi đã cố gắng để thực hiện mã của bạn nhưng tôi đã không có bất kỳ may mắn. Các hành vi chung tôi gặp phải khi giao dịch với các vị trí được xác thực HTTP là với IE7 tất cả đều tốt nhưng trong Firefox khi tôi cố gắng tải tệp lên máy chủ, nó sẽ hiển thị lời nhắc xác thực HTTP - ngay cả khi được cung cấp đúng chi tiết, chỉ đơn giản là quầy hàng quá trình tải lên.

Tôi tin rằng lý do IE7 là ok xuống thông tin phiên/xác thực đang được chia sẻ bởi trình duyệt và thành phần Flash - tuy nhiên, trong Firefox đây không phải là trường hợp và tôi gặp phải hành vi trên.

Đây là chức năng upload cập nhật của tôi, kết hợp với những thay đổi của bạn:

private function pergress():void 
{ 
if (fileCollection.length == 0) 
    { 
    var urlString:String = "upload_process.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&filetotal="+fileTotal; 
    if (ExternalInterface.available) 
    { 
    ExternalInterface.call("uploadComplete", urlString); 
    } 
    } 
if (fileCollection.length > 0) 
    { 
    fileTotal++; 
    var urlRequest:URLRequest = new URLRequest("upload_file.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&obfuscate="+obfuscateHash+"&sessidpass="+sessionPass); 
    urlRequest.method = URLRequestMethod.POST; 
    urlRequest.data = new URLVariables("name=Bryn+Jones"); 
    var encoder:Base64Encoder = new Base64Encoder(); 
    encoder.encode("testuser:testpass"); 
    var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString()); 
    urlRequest.requestHeaders.push(credsHeader); 

    file = FileReference(fileCollection.getItemAt(0)); 
    file.addEventListener(Event.COMPLETE, completeHandler); 
    file.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus); 
    file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress); 
    file.upload(urlRequest); 
    } 
} 

Như đã trình bày ở trên, tôi dường như được trải qua những kết quả tương tự có hoặc không có sửa đổi chức năng của tôi.

Tôi cũng có thể hỏi vị trí đặt crossdomain.xml - vì hiện tại tôi không có và không chắc chắn vị trí đặt nó.

+0

crossdomain.xml nên được đặt trong thư mục gốc của ứng dụng web của bạn. Vì vậy, nếu các tệp bao gồm www.yoursite.com được đặt trong D: \ websites \ yoursite.com, đường dẫn của tệp phải là d: \ websites \ yoursite.com \ crossdomain.xml. –

+0

Ngoài việc đặt tệp corssdomain.xml của bạn (bạn nên làm gì), bạn có biết phiên bản trình phát Flash nào bạn đã cài đặt không? Bạn đã chắc chắn rằng mình đang sử dụng Flash Player 10 chưa? (Có vẻ như phát hiện của tôi là Flash Player 9 không chơi tốt với tiêu đề Ủy quyền tùy chỉnh.) –

+0

Cảm ơn sự giúp đỡ của bạn Christian - thật không may, tôi đã không có cơ hội thử nghiệm thêm (đã bị tràn ngập với một dự án khác) nhưng tôi sẽ cố gắng để tôi có cơ hội. – BrynJ

Trả lời

18

Cú pháp là một chút khác nhau cho URLRequest, nhưng ý tưởng là như nhau:

private function doWork():void 
{ 
    var req:URLRequest = new URLRequest("http://yoursite.com/yourservice.ext"); 
    req.method = URLRequestMethod.POST; 
    req.data = new URLVariables("name=John+Doe"); 

    var encoder:Base64Encoder = new Base64Encoder();   
    encoder.encode("yourusername:yourpassword"); 

    var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString()); 
    req.requestHeaders.push(credsHeader); 

    var loader:URLLoader = new URLLoader(); 
    loader.load(req); 
} 

Một vài điều cần lưu ý:

  • tốt nhất tôi có thể nói, đối với một số lý do , điều này chỉ hoạt động khi phương thức yêu cầu là POST; tiêu đề không được đặt với yêu cầu GET.

  • Điều thú vị là nó cũng không thành công trừ khi ít nhất một cặp tên giá trị URLVariables được đóng gói cùng với yêu cầu, như được chỉ ra ở trên. Đó là lý do tại sao nhiều ví dụ bạn thấy ở đó (bao gồm cả tôi) đính kèm "name = John + Doe" - nó chỉ là trình giữ chỗ cho một số dữ liệu mà URLRequest dường như yêu cầu khi đặt bất kỳ tiêu đề HTTP tùy chỉnh nào. Không có nó, ngay cả một yêu cầu POST được xác thực đúng cũng sẽ không thành công.

  • Rõ ràng, Flash phiên bản máy nghe nhạc 9.0.115.0 hoàn toàn khối tất cả các tiêu đề Authorization (thêm thông tin về cái này here), vì vậy có thể bạn sẽ muốn giữ ý nghĩ đó, quá.

  • Bạn gần như chắc chắn sẽ phải sửa đổi tên miền chéo của mình.tệp xml để chứa (các) đầu trang bạn sẽ gửi. Trong trường hợp của tôi, tôi đang sử dụng tệp này, đây là một tệp chính sách khá rộng mở mà nó chấp nhận từ bất kỳ miền nào, vì vậy trong trường hợp của bạn, bạn có thể muốn hạn chế nhiều hơn một chút, tùy thuộc vào mức độ bảo mật của bạn .

crossdomain.xml:

<?xml version="1.0"?> 
<cross-domain-policy> 
    <allow-access-from domain="*" /> 
    <allow-http-request-headers-from domain="*" headers="Authorization" /> 
</cross-domain-policy> 

... và điều đó dường như làm việc; biết thêm thông tin về điều này có sẵn từ Adobe here).

Mã ở trên đã được thử nghiệm với trình phát Flash 10 (với gỡ lỗi & SWF phát hành), vì vậy nó sẽ phù hợp với bạn, nhưng tôi muốn cập nhật bài đăng gốc của mình để bao gồm tất cả thông tin bổ sung này trong trường hợp bạn gặp phải bất kỳ sự cố nào, như những cơ hội dường như (đáng buồn) có khả năng là bạn sẽ.

Hy vọng điều đó sẽ hữu ích! Chúc may mắn. Tôi sẽ theo dõi nhận xét.

+0

Tones lời khuyên cho cùng một điều nhưng câu trả lời chỉ làm việc thực tế làm việc cho ứng dụng flex đơn giản với sdk 4.6. Cảm ơn nhiều. – serkan

+0

điều này làm việc với as3 ide cũng như cảm ơn bạn. – sputn1k

1

Tôi không chắc chắn về điều này nhưng bạn đã thử thêm tên người dùng: mật khẩu @ vào đầu url của bạn chưa?

"http://username:[email protected]/yourservice.ext"

+0

Sử dụng cách này có vẻ là cách duy nhất để gửi thông tin ủy quyền bằng cách sử dụng yêu cầu GET – Arpit

+0

Rõ ràng đây là một chuỗi cũ, nhưng chỉ cần ném nó ra khỏi đó phương pháp thêm 'username: password @ ...' làm việc cho tôi, việc thêm các tiêu đề Auth cơ bản không hoạt động mà không hiển thị hộp thoại xác thực trong ứng dụng AIR của tôi. – dierdre

0

vấn đề tương tự Dường như đã được giải quyết here. Tôi khuyên bạn cũng nên kiểm tra số Flexcoders post được liên kết trong bài đăng đầu tiên.

Sự cố là FireFox sử dụng một cá thể cửa sổ trình duyệt riêng biệt để gửi yêu cầu tải lên tệp. Giải pháp là tự đính kèm id phiên vào url yêu cầu. Id phiên không được đính kèm dưới dạng biến GET thông thường, nhưng với dấu chấm phẩy (lý do cho cú pháp này không được biết đến với tôi).

+0

Tôi cũng đã gặp phải vấn đề phiên này và đưa ra giải pháp tương tự, nhưng đây không phải là vấn đề phải đối mặt ở đây - đó là xác thực HTTP cụ thể (không phải phiên liên quan như vậy). – BrynJ

0

Flash rất hạn chế về loại tiêu đề bạn có thể chuyển với yêu cầu http (và nó thay đổi giữa các trình duyệt và OS). Nếu bạn nhận được điều này để làm việc trên một trình duyệt/hệ điều hành, hãy chắc chắn rằng bạn kiểm tra nó trên những người khác.

Điều tốt nhất cần làm là không gây rối với tiêu đề HTTP.

Chúng tôi gặp sự cố tương tự (tải lên Anbom Web Picasa từ flash) và đăng thông qua proxy trên máy chủ của chúng tôi. Chúng tôi chuyển các tiêu đề phụ qua thông số bài đăng và proxy của chúng tôi thực hiện đúng.

1
var service : HTTPService = new HTTPService(); 
var encoder:Base64Encoder = new Base64Encoder(); 
encoder.insertNewLines = false; 
encoder.encode("user:password"); 

service.headers = {Authorization:"Basic " + encoder.toString()}; 
service.method = HTTPRequestMessage.POST_METHOD; 
service.request = new URLVariables("name=John+Doe"); 
service.addEventListener(FaultEvent.FAULT,error_handler); 
service.addEventListener(ResultEvent.RESULT,result_handler); 
service.url = 'http://blah.blah.xml?'+UIDUtil.createUID(); 
service.send(); 
+0

Xin chào các bạn, cảm ơn các ý tưởng của bạn, tôi đã tìm cách hack bằng cách sử dụng HTTPService thay vì URLRequest. Tất cả những gì tôi đã làm là thêm biến thông qua service.request và đặt service.method = 'POST' Hy vọng trợ giúp !!! :) –

0

Đây là một công việc xung quanh khi sử dụng ASP.Net dựa một phần vào công việc here.

Tôi đã tạo một thành phần tự động ghi các đối tượng Flex vào trang để chúng có thể được sử dụng trong UpdatePanels. Gửi tin nhắn cho tôi nếu bạn muốn họ viết mã.Để giải quyết vấn đề trên trong các trang mà cookie xác thực sẽ cần được gửi bởi URLRequest, tôi thêm các giá trị vào dưới dạng flashVars.

Mã này chỉ hoạt động trong đối tượng của tôi, nhưng bạn sẽ có được ý tưởng

Dictionary<string, string> flashVars = new Dictionary<string, string>();  
flashVars.Add("auth", Request.Cookies["LOOKINGGLASSFORMSAUTH"].Value); 
flashVars.Add("sess", Request.Cookies["ASP.NET_SessionId"].Value); 
myFlexObject.SetFlashVars(flashVars); 

Sau đó, trong Object Flex, kiểm tra các params

if (Application.application.parameters.sess != null) 
    sendVars.sess= Application.application.parameters.sess; 
if (Application.application.parameters.auth != null) 
    sendVars.au= Application.application.parameters.auth; 

request.data = sendVars; 
request.url = url; 
request.method = URLRequestMethod.POST; 

Cuối cùng nhồi cookie trong trên global.asax BeginRequest

if (Request.RequestType=="POST" && Request.Path.EndsWith("upload.aspx")) 
{ 
    try 
    { 
     string session_param_name = "sess"; 
     string session_cookie_name = "ASP.NET_SESSIONID"; 
     string session_value = Request.Form[session_param_name]; // ?? Request.QueryString[session_param_name]; 
     if (session_value != null) { UpdateCookie(session_cookie_name, session_value); } 
    } 
    catch (Exception) { } 

    try 
    { 
     string auth_param_name = "au"; 
     string auth_cookie_name = FormsAuthentication.FormsCookieName; 
     string auth_value = Request.Form[auth_param_name];// ?? Request.QueryString[auth_param_name]; 

     if (auth_value != null) { UpdateCookie(auth_cookie_name, auth_value); } 
    } 
    catch (Exception) { } 

} 

Hy vọng điều này giúp ai đó tránh được 6 giờ tôi vừa mới giải quyết vấn đề này. Adobe đã đóng cửa vấn đề này là không thể giải quyết được, vì vậy đây là phương sách cuối cùng của tôi.

2

Nếu bạn muốn tải lên tệp, bạn chỉ cần gửi tiêu đề chính xác và nội dung tệp bằng cách sử dụng URLRequest qua lớp UploadPostHelper. Điều này hoạt động 100%, tôi đang sử dụng lớp này để tải lên các tệp hình ảnh và tệp CSV được tạo nhưng bạn có thể tải lên bất kỳ loại tệp nào.

Lớp này chỉ đơn giản là chuẩn bị yêu cầu với tiêu đề và nội dung như thể bạn đang tải lên tệp từ biểu mẫu html.

http://code.google.com/p/as3asclublib/source/browse/trunk/net/UploadPostHelper.as?r=118

_urlRequest = new URLRequest(url); 
     _urlRequest.data = "LoG"; 
     _urlRequest.method = URLRequestMethod.POST; 

     _urlRequest.requestHeaders.push(new URLRequestHeader("X-HTTP-Code-Override", "true")); 
     _urlRequest.requestHeaders.push(new URLRequestHeader("pragma", "no-cache")); 

     initCredentials(); 
_loader.dataFormat = URLLoaderDataFormat.BINARY; 
      //this creates a security problem, putting the content type in the headers bypasses this problem 
      //_urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary(); 
      _urlRequest.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache')); 
      _urlRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary())); 
      _urlRequest.data = UploadPostHelper.getPostData("file.csv", param[1]); 

     _loader.load(_urlRequest);