ホームページ  >  記事  >  ウェブフロントエンド  >  JS および WebService の大きなファイルのアップロード コード共有

JS および WebService の大きなファイルのアップロード コード共有

小云云
小云云オリジナル
2018-03-07 15:23:492431ブラウズ

フロントエンドを作成する過程で、ユーザーがより大きなファイルをアップロードしようとすると、サーバーによって制限され、アップロードできなくなります。サーバーが受け入れるファイルのサイズを調整します。 設定方法は次のとおりです:

ASP で Web.config ファイルの httpRuntime を設定します:

<httpRuntime executionTimeout="90" maxRequestLength="40960" useFullyQualifiedRedirectUrl="false"minFreeThreads="8" 
minLocalRequestFreeThreads="4" appRequestQueueLimit="100" enableVersionHeader="false"/>

各パラメータの役割は次のとおりです:

executionTimeout:リクエストの実行に許可される最大時間制限 (秒単位)。
maxRequestLength: ASP.NET でサポートされる最大ファイル アップロード サイズを示します。この制限は、ユーザーがサーバーに大量のファイルを渡すことによって引き起こされるサービス拒否攻撃を防ぐために使用できます。指定されたサイズは KB 単位です。デフォルト値は 4096KB (4 MB) です。
useFullyQualifiedRedirectUr: クライアント リダイレクトが完全修飾されているかどうか (一部のモバイル コントロールに必要な「http://server/path」形式)、または代わりに相対リダイレクトをクライアントに送信するかどうかを示します。 True の場合、完全修飾されていないすべてのリダイレクトは、完全修飾形式に自動的に変換されます。 false はデフォルトのオプションです。
minFreeThreads: 新しいリクエストの実行が許可される空きスレッドの最小数を示します。 ASP.NET は、処理を完了するために追加のスレッドが必要な要求のために、指定された数のスレッドを空き状態に保ちます。デフォルト値は 8 です。
minLocalRequestFreeThreads: ASP.NET によって維持され、新しいローカル要求を実行できる空きスレッドの最小数を示します。この数のスレッドは、一部のリクエストが処理中にローカル ホストに対してサブリクエストを行う場合に備えて、ローカル ホストからの受信リクエスト用に予約されています。これにより、Web サーバーへの再帰的な再入によって発生する可能性のあるデッドロックが回避されます。
appRequestQueueLimit: ASP.NET がアプリケーションのキューに入れるリクエストの最大数を表します。リクエストを処理するのに十分な空きスレッドがない場合、リクエストはキューに入れられます。キューがこの設定で指定された制限を超えると、受信リクエストは「503 - サーバーがビジー状態」エラー メッセージで拒否されます。 EnableVersionHeader: ASP.NET がバージョン ヘッダーを出力するかどうかを指定します。 Microsoft Visual Studio 2005 は、このプロパティを使用して、現在使用されている ASP.NET のバージョンを判断します。運用環境では、このプロパティは必須ではないため、無効にすることができます。

ただし、サーバー構成にアップロードされたファイルが十分な大きさであっても、IIS によって制限され、ユーザーに安全なサービスを提供できません。では、大きなファイルのアップロードの問題を解決する方法はあるのでしょうか?
必ず 1 つあります: マルチパート アップロードです。
複数のアップロードとは、アップロードするファイルをフロントエンドで非常に小さな部分に分割し、それをサーバーに渡し、サーバーからファイルを完全なファイルに結合することを指します。
フロントエンドから始めましょう。マルチパート アップロード プロセス中に、フロントエンド タスクはファイルを断片化することです。たとえば、断片化には WebUpLoader が提供するアップロード コンポーネントを使用できます。または、JS と JQ が提供するアップロード コンポーネントを使用することもできます。コードの例は次のとおりです。

var BYTES_PER_CHUNK = 1024 * 1024; // 每个文件切片大小定为1MB .
var slices;
var totalSlices;

//发送请求
function sendRequest() {
var blob = document.getElementById("yourID").files[0];
var start = 0;
var end;
var index = 0;


// 计算文件切片总数
slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
totalSlices= slices;
while(start < blob.size) {
end = start + BYTES_PER_CHUNK;
if(end > blob.size) {
end = blob.size;
}
uploadFile(blob, index, start, end);
start = end;
index++;
if ( index>=totalSlices )
alert("Complete!!");
}
}

//上传文件
function uploadFile(blob, index, start, end) {
var xhr;
var fd;
var chunk;  
var sliceIndex=blob.name+index;
chunk =blob.slice(start,end);//切割文件

fd = new FormData();
fd.append("FileName", chunk, sliceIndex);
var xhr = new XMLHttpRequest();
xhr.open(&#39;POST&#39;, &#39;Server URL&#39;, false);//false,同步上传;ture,异步上传
xhr.send(fd);
if((xhr.status >=200 && xhr.status < 300) || xhr.status == 304){
setTimeout("",10);
}else{
uploadFile(blob, index, start, end);
}
}

フロントエンドではもちろん、バックエンドでの受け入れと結合が不可欠です。 .Net を例に、ファイルを受信して​​結合する方法を説明します。

public void RecoveryKPJD()
        {
            HttpContext context = System.Web.HttpContext.Current;
            context.Response.ContentType = "text/plain";
            //如果进行了分片
            if (context.Request.Form.AllKeys.Any(m => m == "chunk"))
            {
                //取得chunk和chunks
                int chunk = Convert.ToInt32(context.Request.Form["chunk"]);//当前分片在上传分片中的顺序(从0开始)
                int chunks = Convert.ToInt32(context.Request.Form["chunks"]);//总分片数
                //根据GUID创建用该GUID命名的临时文件夹
                string folder = Your Path + context.Request["guid"] + "/";
                string path = folder + chunk;


                //建立临时传输文件夹
                if (!Directory.Exists(Path.GetDirectoryName(folder)))
                {
                    Directory.CreateDirectory(folder);
                }

                FileStream addFile = new FileStream(path, FileMode.Append, FileAccess.Write);
                BinaryWriter AddWriter = new BinaryWriter(addFile);
                //获得上传的分片数据流
                HttpPostedFile file = context.Request.Files[0];
                Stream stream = file.InputStream;

                BinaryReader TempReader = new BinaryReader(stream);
                //将上传的分片追加到临时文件末尾
                AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
                //关闭BinaryReader文件阅读器
                TempReader.Close();
                stream.Close();
                AddWriter.Close();
                addFile.Close();

                TempReader.Dispose();
                stream.Dispose();
                AddWriter.Dispose();
                addFile.Dispose();
                if (chunk == chunks - 1)
                {
                    //合并文件
                    ProcessRequest(context.Request["guid"], Path.GetExtension(file.FileName));
                }
            }
            else//没有分片直接保存
            {
                string targetPath = ""; //此处写文件的保存路径
                context.Request.Files[0].SaveAs(targetPath);
            }
        }

   private void ProcessRequest(string guid, string fileExt)
        {
            HttpContext context = System.Web.HttpContext.Current;
            context.Response.ContentType = "text/plain";
            string sourcePath = Path.Combine("Your Path", guid + "/");//源数据文件夹
            string targetPath = Path.Combine("Your Path", Guid.NewGuid() + fileExt);//合并后的文件

            DirectoryInfo dicInfo = new DirectoryInfo(sourcePath);
            if (Directory.Exists(Path.GetDirectoryName(sourcePath)))
            {
                FileInfo[] files = dicInfo.GetFiles();
                foreach (FileInfo file in files.OrderBy(f => int.Parse(f.Name)))
                {
                    FileStream addFile = new FileStream(targetPath, FileMode.AppenFileAccess.Write);
                    BinaryWriter AddWriter = new BinaryWriter(addFile);

                    //获得上传的分片数据流
                    Stream stream = file.Open(FileMode.Open);
                    BinaryReader TempReader = new BinaryReader(stream);
                    //将上传的分片追加到临时文件末尾
                    AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
                    //关闭BinaryReader文件阅读器
                    TempReader.Close();
                    stream.Close();
                    AddWriter.Close();
                    addFile.Close();

                    TempReader.Dispose();
                    stream.Dispose();
                    AddWriter.Dispose();
                    addFile.Dispose();
                }
            }
        }

関連する推奨事項:

phpファイルサイズの検出と大きなファイルのアップロード処理

WebServiceを呼び出すNodejsの詳細な説明

クロスドメインでWebServiceを呼び出すJSの簡単な例

以上がJS および WebService の大きなファイルのアップロード コード共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。