ホームページ > ウェブフロントエンド > jsチュートリアル > jQueryのuploadifyが非IEコアブラウザでアップロードできない問題を解決する_jquery

jQueryのuploadifyが非IEコアブラウザでアップロードできない問題を解決する_jquery

WBOY
リリース: 2016-05-16 15:47:14
オリジナル
1200 人が閲覧しました

1. jquery Uploadify 自己紹介:

(1) 皆さん、こんにちは。私は jquery プラグイン ファミリで非同期アップロードの実装を担当しているプラ​​グインです。私だけが使いやすいわけではありません。

(2)、私の機能:

単一ファイルまたは複数ファイルのアップロードをサポートし、同時にアップロードされるファイルの数を制御できます

PHP、.NET、Java など、サーバー側で使用するさまざまな言語をサポートします。

アップロードされるファイルの種類とサイズ制限はパラメータで設定できます

ファイルを選択した後に自動的にアップロードするかどうかはパラメータで設定できます

拡張が簡単で、各ステップのコールバック関数 (onSelect、onCancel...) を制御できます

インターフェースパラメータと CSS を通じて外観を制御

ホームページのアドレスをアップロードしてください: http://www.uploadify.com/ このページで彼について詳しく知ることができます。

(3)、私の使用法:

baidu.com、google.com 検索にアクセスしてください。たくさんあります。

2. Firefox に問題があります。それは私の問題ですか?

jquery Uploadify は IE で正常にアップロードできます。非同期アップロードを実装すると、アップロード時に各ファイルがサーバーにリクエストを送信します。各リクエストには、セキュリティ検証、セッションおよび Cookie の検証が必要です。はい、それだけです。 jquery Uploadify はフラッシュを使用してアップロードを実装するため、データ フロー リクエストがバックグラウンドに送信されるたびに、IE はローカル Cookie ストレージを自動的にバンドルしてサーバーに送信します。しかし、Firefox と Chrome はこれを行わず、安全ではないと考えるでしょう。はー、だから。

理由がわかったので、次の 2 つの概念を理解しましょう:

(1)、セッション:

セッション (セッション状態とも呼ばれる) は、Web システムで最も一般的に使用される状態であり、現在のブラウザー インスタンスに関連する情報を維持するために使用されます。たとえば、ログインしているユーザーのユーザー名をセッションに入れることで、セッション内の特定のキーを判断することでユーザーがログインしているかどうか、ログインしている場合はそのユーザー名を判断できます。

セッションはクライアント (またはブラウザ インスタンス) ごとに「1 つのコピー」であることがわかっています。ユーザーが初めて Web サーバーとの接続を確立すると、サーバーは識別子として SessionID をユーザーに配布します。 SessionID は 24 文字のランダムな文字列です。ユーザーがページを送信するたびに、ブラウザーは HTTP ヘッダーに SessionID を含めて Web サーバーに送信します。これにより、Web サーバーは現在ページを要求しているクライアントを区別できます。では、ASP.NET 2.0 では、SessionID を保存するどのようなモードが提供されているのでしょうか?

(2) Cookie (Cookie という複数形で使用されることもあります) は、ユーザーの身元を特定し、セッション追跡を実行するために、特定の Web サイトによってユーザーのローカル端末に保存されるデータ (通常は暗号化された) を指します。

3. 解決策

1.asp.net 環境

Global.asax ファイルに次のコードを記述します:

void Application_BeginRequest(object sender, EventArgs e)  
  {
    try { 
      string session_param_name = "ASPSESSID"; 
      string session_cookie_name = "ASP.NET_SessionId"; 
      if (HttpContext.Current.Request.Form[session_param_name] != null) 
      { 
        UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]); 
      } 
      else if (HttpContext.Current.Request.QueryString[session_param_name] != null) 
      { 
        UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]); 
      } 
    }
    catch { 
    } 

    //此处是身份验证
    try { 
      string auth_param_name = "AUTHID"; 
      string auth_cookie_name = FormsAuthentication.FormsCookieName; 
      if (HttpContext.Current.Request.Form[auth_param_name] != null) 
      { 
        UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]); 
      } 
      else if (HttpContext.Current.Request.QueryString[auth_param_name] != null) 
      { 
        UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
      } 
    }
    catch { }
  }

  private void UpdateCookie(string cookie_name, string cookie_value)
  {
    HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
    if (null == cookie)
    {
      cookie = new HttpCookie(cookie_name);
    }
    cookie.Value = cookie_value;
    HttpContext.Current.Request.Cookies.Set(cookie);//重新设定请求中的cookie值,将服务器端的session值赋值给它
  }

ログイン後にコピー

/*---------------Aspx ページ側コード-------------- ------------------*/

   this.hfAuth.Value = Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value;
   

   this.hfAspSessID.Value = Session.SessionID;

ログイン後にコピー

セッション値と認証値をクライアント コントロールに保存すると、js を通じてこれら 2 つの値を取得し、次のプラグイン js 初期化プログラムに渡すことができます。

(セッション値をコントロールに保存することを選択した理由は、クライアントが Cookie を無効にするのではないかと心配だからです。)

/*--------------------------------以下は js コードです---------- ----- -----------------------*/

  InitUpload: function(auth, AspSessID) {
    $("#uploadify").uploadify({
      uploader: 'Scripts/jqueryplugins/Infrastructure/uploadify.swf',
      script: 'Handlers/ResourceHandler.ashx?OpType=UploadResource',
      cancelImg: 'Scripts/jqueryplugins/Infrastructure/cancel.png',
      queueID: 'fileQueue',
      sizeLimit: '21480000000',
      wmode: 'transparent ',
      fileExt: '*.zip,*.jpg, *.rar,*.doc,*.docx,*.xls,*.xlsx,*.png,*.pptx,*.ppt,*.pdf,*.swf,*.txt',
      auto: false,
      multi: true,
      scriptData: { ASPSESSID: AspSessID, AUTHID: auth },

ログイン後にコピー

しかし

プラグインが初期化されるとき、ローカルに記録されたセッション値と認証値をパラメータ割り当ての初期化メソッドに渡します。このようにして、ファイルをアップロードするための非同期リクエストが行われるたびに、対応するセッション値が返されます。リクエストファイルに含まれています。

2.C# 環境

上記は asp.net での解決策ですが、C# ではどのように処理すればよいでしょうか?

これは、ファイルをアップロードするためのすべてのコードを変更する必要がないように、これを解決した方法です。変更の量は最小限ですが、セキュリティ上のリスクがあります。

if (this.LoginInfo == null)
{
  // 解决uploadify兼容火狐谷歌浏览器上传问题
  // 但是,此代码使系统有安全隐患,Flash程序请求该系统不需要验证
  // 要解决此安全隐患,需要Flash程序传用户名和密码过来验证,但是该用户名和密码不能写在前端以便被不法用户看到
  if (Request.UserAgent == "Shockwave Flash")
  {
    return;
  }
  else
  {
    filterContext.Result = RedirectToAction("LoginAgain", "Account", new { Area = "Auth" });
    return;
  }
}

ログイン後にコピー
私たちのシステムは ASP.NET MVC に基づいていますが、ユーザーは暗号化によって機密情報を見ることはできませんが、悪意のあるユーザーはシステム検証をバイパスするために機密情報を復号する必要はありません。

検証情報をフロントエンドに直接書き込むことはできません。ajax を使用してバックエンドから検証情報を取得し、それをフラッシュに渡し、インターセプターで検証することができます。

変更後:

JS コード:

ajax はバックグラウンドにユーザー名を取得するよう要求し、それを flash に渡します

$(function () {
  $.ajax({
    url: "/Auth/Account/GetUserNamePwd",
    type: "POST",
    dataType: "json",
    data: {},
    success: function (data) {
      $("#uploadify").uploadify({
        height: 25,
        width: 100,
        swf: '/Content/Plugins/UploadifyJs/uploadify.swf',
        uploader: 'UploadFile',
        formData: {
          userName: data.data.userName, //ajax获取的用户名
          pwd: data.data.pwd //ajax获取的密码
        },
        buttonText: '选择文件上传',
        fileSizeLimit: '4MB',
        fileTypeDesc: '文件',
        fileTypeExts: '*.*',
        queueID: 'fileQueue',
        multi: true,
        onUploadSuccess: function (fileObj, data, response) {
          var d = eval("(" + data + ")");
          $(".uploadify-queue-item").find(".data").html("  上传完成");
          $("#url").val(d.url);
          $("#name").val(d.name);
        },
        onUploadError: function (event, ID, fileObj, errorObj) {
          if (event.size > 4 * 1024 * 1024) {
            alert('超过文件上传大小限制(4M)!');
            return;
          }
          alert('上传失败');
        }
      }); //end uploadify
    }
  });
});    //end $

ログイン後にコピー

拦截器中代码:

......
if (this.LoginInfo == null)
{ 
  // 解决uploadify兼容火狐谷歌浏览器上传问题
  // 但是,此代码使系统有安全隐患,Flash程序请求该系统不需要验证
  // 要解决此安全隐患,需要Flash程序传用户名和密码过来验证,但是该用户名和密码不能写在前端以便被不法用户看到
  if (Request.UserAgent == "Shockwave Flash")
  {
    string userName = Request.Params["userName"];
    string pwd = Request.Params["pwd"];
    if (!string.IsNullOrWhiteSpace(userName) && !string.IsNullOrWhiteSpace(pwd))
    {
      AuthDAL authDAL = new AuthDAL();
      sys_user user = authDAL.GetUserInfoByName(userName);
      if (user != null && user.password == pwd)
      {
        return;
      }
    }
  }
  else
  {
    filterContext.Result = RedirectToAction("LoginAgain", "Account", new { Area = "Auth" });
    return;
  }
}
......
ログイン後にコピー

3.jsp版解决方法

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">


<%
	String syscontext = request.getContextPath();

%>

<% 
  String path = request.getContextPath(); 
  String basePath = request.getScheme() + "://" 
      + request.getServerName() + ":" + request.getServerPort() 
      + path; 
  
  String sessionid = session.getId();
  
%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="<%=syscontext %>/webcontent/resourceManage/wallpapaer/uploadify/uploadify.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="<%=syscontext %>/webcontent/resourceManage/wallpapaer/uploadify/jquery.uploadify-3.1.min.js"></script>

<!-- 注意我使用的jquery uploadify版本-->


<script type="text/javascript">
//用来计算上传成功的图片数
var successCount = 1;

$(function() {
	var uploadUrl = '<%=basePath%>/uploadresource.do;jsessionid=<%=sessionid%>&#63;Func=uploadwallpaper2Dfs';
	
	var swfUrl2 = "<%=basePath%>/webcontent/resourceManage/wallpapaer/uploadify/uploadify.swf";
  $('#file_upload').uploadify({
    'swf'   : swfUrl2,
    'uploader' : uploadUrl,
    // Put your options here
    'removeCompleted' : false,
    'auto' : false,
    'method'  : 'post',
    'onUploadSuccess' : function(file, data, response) {
      add2SuccessTable(data);
    }
  });
});



/**
 * 将成功上传的图片展示出来
 */
function add2SuccessTable(data){
	var jsonObj = JSON.parse(data);
	for(var i =0; i < jsonObj.length; i++){
		var oneObj = jsonObj[i];
		var fileName = oneObj.fileName;
		var imgUrl = oneObj.imgUrl;
		
		var td_FileName = "<td>"+fileName+"</td>";
		var td_imgUrl = "<td><img width='150' src='"+imgUrl+"'></img></td>";
		var oper = "<td><input type='button' value='删除' onclick='deleteRow("+successCount+")'/></td>";
		var tr = "<tr id='row"+successCount+"'>"+successCount+td_FileName+td_imgUrl+oper+"</tr>";
		
		$("#successTable").append(tr);
		
		successCount++;
	}
	
}



function deleteRow(i){
	$("#row"+i).empty();
	$("#row"+i).remove();
}
</script>


<title>Insert title here</title>
</head>
<body>
<input type="file" name="file_upload" id="file_upload" />
	<p> 
		<a href="javascript:$('#file_upload').uploadify('upload','*')">开始上传</a>  
		<a href="javascript:$('#file_upload').uploadify('cancel', '*')">取消所有上传</a>
	</p> 
<table id="successTable">
	<tr>
		<td>文件名</td>
		<td>图片</td>
		<td>操作</td>
	</tr>
</table>
</body>
</html>
ログイン後にコピー

总结

简单的说,最终的解决办法就是可以在每个引用的文件后面加个随机数,让它每次请求都带个参数,该问题则自动解决

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート