Flex 3 - 如何支持 HTTP 身份验证 URLRequest?
-
21-08-2019 - |
题
我有一个 Flex 文件上传脚本,它使用 URLRequest 将文件上传到服务器。我想添加对 http 身份验证(服务器上受密码保护的目录)的支持,但我不知道如何实现这一点 - 我认为我需要以某种方式扩展该类,但对于如何实现我有点迷失。
我尝试修改以下内容(用 URLRequest 替换 HTTPService),但这不起作用。
private function authAndSend(service:HTTPService):void{
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("someusername:somepassword");
service.headers = {Authorization:"Basic " + encoder.toString()};
service.send();
}
我应该指出,尽管我已经成功地对上传脚本进行了一些修改,但我对 ActionScript / Flex 并不了解。
[编辑] - 这是我的进度更新,基于下面的答案,尽管我仍然无法让它工作:
谢谢您的帮助。我试图实现你的代码,但我没有任何运气。
在处理 HTTP 身份验证位置时,我遇到的一般行为是,使用 IE7 一切正常,但在 Firefox 中,当我尝试将文件上传到服务器时,它会显示 HTTP 身份验证提示 - 即使提供了正确的详细信息,也会停止上传过程。
我相信 IE7 正常的原因在于浏览器和 Flash 组件共享会话/身份验证信息 - 然而,在 Firefox 中情况并非如此,我遇到了上述行为。
这是我更新的上传功能,包含您的更改:
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);
}
}
如上所述,无论是否对我的功能进行修改,我似乎都遇到了相同的结果。
我还可以问 crossdomain.xml 应该位于哪里吗 - 因为我目前没有,并且不确定将其放置在哪里。
解决方案
URLRequest 的语法略有不同,但想法是相同的:
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);
}
有几点需要记住:
据我所知,出于某种原因,这只适用于请求方法为 POST 的情况;标头不会通过 GET 请求设置。
有趣的是,除非至少有一个 URLVariables 名称-值对与请求打包在一起,否则它也会失败,如上所述。这就是为什么您看到的许多示例(包括我的)都附加了“name=John+Doe”——它只是 URLRequest 在设置任何自定义 HTTP 标头时似乎需要的一些数据的占位符。如果没有它,即使经过正确身份验证的 POST 请求也会失败。
显然,Flash播放器版本 9.0.115.0 完全阻止所有授权标头(有关此的更多信息 这里),所以您可能也想记住这一点。
您几乎肯定需要修改 crossdomain.xml 文件以适应您要发送的标头。就我而言,我使用的是这个,这是一个相当开放的策略文件,因为它接受来自任何域的内容,因此在您的情况下,您可能需要更多地限制事情,具体取决于您的安全意识如何。
跨域.xml:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-http-request-headers-from domain="*" headers="Authorization" />
</cross-domain-policy>
...这似乎有效;Adobe 提供了有关此内容的更多信息 这里).
上面的代码是使用 Flash Player 10(带有调试和发布 SWF)进行测试的,因此它应该适合您,但我想更新我的原始帖子以包含所有这些额外信息,以防您遇到任何问题,因为可能性似乎很大(可悲的是)你很可能会的。
希望能帮助到你!祝你好运。我会留意评论的。
其他提示
对FileReference.upload()和FileReference.download()方法不支持请将URLRequest.requestHeaders参数。
http://livedocs.adobe.com/flex /2/langref/flash/net/URLRequest.html
如果你想上传一个文件,你只需要发送正确的头,并通过UploadPostHelper类使用的URLRequest文件的内容。该工程100%,我使用这个类来上传生成的图像和CSV文件,但你可以上传任何类型的文件。
此类简单地准备带有头部和,如果你将被上载从一个html形式与该文件内容的请求。
HTTP://代码。 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);
我不知道这个,但有你尝试添加用户名:密码@到您的网址的开头
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();
表面上类似的问题得到解决此处。我劝你也检查 Flexcoders帖子链接到第一篇文章。
<强>问题强>是,Firefox使用一个单独的浏览器窗口实例发送文件上传请求。的将溶液强>是会话ID手动附加到请求URL。会话ID是不附着作为常规GET变量,但用分号(对于此语法的原因是未知的我)。
Flash 在可以通过 http 请求传递的标头类型方面非常有限(并且它在浏览器和操作系统之间会发生变化)。如果您让它在一种浏览器/操作系统上运行,请确保在其他浏览器/操作系统上进行测试。
最好的办法就是不要弄乱 HTTP 标头。
我们有同样的问题(从 Flash 上传到 Picasa 网络相册)并通过我们服务器上的代理进行发布。我们将额外的标头作为 post 参数传递,并且我们的代理做了正确的事情。
“ HTTP://用户名:password@yoursite.com/yourservice.ext 一>“
这个不工作在IE(的http:// WWW。 theregister.co.uk/2004/01/30/ms_drop_authentication_technique/ )似乎并没有在Chrome工作要么。
可能在Flash中不能使用
下面是一个变通地基于所述工作此处一部分使用时ASP.Net >
我建立动态写入Flex对象的页面,以便它们可以在被UpdatePanel的使用的组件。给我发短信,如果你想他们的代码。为了解决在身份验证Cookie将需要通过的URLRequest发送网页上面的问题,我作为flashVars中添加值。
此代码只能在我的对象,但你的想法
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);
然后在Flex对象,检查该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;
最后东西的饼干上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) { }
}
希望这有助于避免有人的6个小时里,我只花了解决该问题。 Adobe已经关闭了该问题的无法解决的,所以这是我的最后一招。