質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.04%

asp.net ajax upload でエラーになる

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 113

Qoo

score 1062

下記のコードでhtmlから画像をアップロードしたいのですが、
開発環境 windows10 + visualstudio comminity 2017でだと正常にアップロードでき
本番環境 windows2012 r2 iis(8.5.9600.16384)だとエラーになってしまいます。

ディレクトリ自体の権限はIISuserがフルアクセスできるように設定済です。
JSでのエラーでは「失敗object object」 となってしまい、どこでエラーになっているかがわかりません

なにか考えられる方法、エラーの内容を受け取る方法を教授頂きたいです
よろしくお願いいたします

//アップロード
function upload() {
  var data = new FormData();
  var fileUpload = $("#FileUpload1").get(0);
  var files = fileUpload.files;
  for (var i = 0; i < files.length; i++) {
    data.append('photo', upload_blob, files[i].name);
  }
  //ディレクトリパス追加
  data.append('dir', 'upload');
  var now = new Date();
  var strfilename = "" + now.getFullYear() + padZero(now.getMonth() + 1) + padZero(now.getDate()) + padZero(now.getHours()) + padZero(now.getMinutes()) + padZero(now.getSeconds());
  //年月日時分秒の文字列の作成(YYYYMMDDHHMMSS)これがファイル名に
  data.append('comment', strfilename);
  alert("Filename" + strfilename);
  var options = {};
  options.url = "FileUploadHandler.ashx";
  options.type = "POST";
  options.data = data;
  options.contentType = false;
  options.processData = false;
  options.success = function (result) {
    //アップロード完了
    alert("成功" + result);
  };
  options.error = function (err) {
    //アップロード失敗
    alert("失敗" + err);
  };
  event.preventDefault();
  $.ajax(options);
}
<%@ WebHandler Language="C#" Class="FileUploadHandler" %>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;

public class FileUploadHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {

        try
        {


            if (context.Request.Form["dir"] != "")
            {

                if (context.Request.Files.Count > 0)
                {
                    HttpFileCollection files = context.Request.Files;

                    for (int i = 0; i < 1; i++)
                    {
                        HttpPostedFile file = files[i];

                        string txtcomment = context.Request.Form["comment"];
                        string fname = txtcomment + ".jpg";
                        string fnamepath = context.Server.MapPath("uploads/" + fname);
                        file.SaveAs(fnamepath);

                    }

                }

                context.Response.ContentType = "text/plain";
                context.Response.Write("Successfully!");

            }
        }
        catch (Exception e)
        {
            context.Response.Write("Failure!" + e.ToString());
        }




    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}

web.configの情報も追記します
文字制限のため、こちらにアップしました。

web.config

Fiddlerのキャプチャ
イメージ説明

テストコードをアップ
テストコード

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/11/09 12:35

    alert()ではオブジェクト内部は展開されないのでconsole.log()にてブラウザ委開発ツールより内容確認して質問に追記してください

    キャンセル

  • m.ts10806

    2019/11/09 12:37

    それかメッセージだけ欲しければ
    err.messageですね。
    https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error

    キャンセル

  • Qoo

    2019/11/09 13:02

    ありがとうございます!
    スマホでconsole.log()確認する方法がわからなかったので、PCでテストしたところ問題なくアップロードできました(泣)

    アップロードする画像サイズの問題なのでしょうか。。。

    アップロードできたファイルは7.5kb
    アップロードできなかったファイルはスマホで撮影した画像662kb

    でした。

    一応asp.net のweb.confgで最大アップロード容量は設定しているつもりなのですが、、
    効いてないのでしょうか。。。

    <system.webServer>
    <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <modules runAllManagedModulesForAllRequests="true" />
    <security>
    <requestFiltering>
    <requestLimits maxAllowedContentLength="1000000000" />
    </requestFiltering>
    </security>
    </system.webServer>

    キャンセル

回答 1

checkベストアンサー

+3

コメント欄では画像が貼れないので回答欄に書きます。

IIS Express では問題なくて IIS ではダメと言うことですと、まず頭に浮かぶのは context.Server.MapPath("uploads/" + fname); で取得できるフォルダに対する IIS のワーカープロセスのアクセス権なのですが、そこは問題ないのですか?

IIS のワーカープロセスの属するグループは IIS_IUSRS です。それに書き込み権限を与えればアップロードされたファイルをそこに書き込むことはできるはずです。

イメージ説明

FIddler を使って要求・応答をキャプチャして、応答の WebView か TextView を見てください。以下の画像のようなエラー情報が取れているかもしれません。

イメージ説明

上の画像は以下の記事のように jQuery.ajax を使って画像をアップロードした時、Controller で疑似的に例外をスローしたものです。

MVC でファイルのアップロード
http://surferonwww.info/BlogEngine/post/2019/08/03/file-upload-on-aspnet-mvc-application.aspx

上の記事のコードの .fail(function( jqXHR, textStatus, errorThrown ) で表示されるのは textStatus: error, errorThrown: Internal Server Error ぐらいで詳しい情報は分かりませんが、debug を有効にしてあれば上のような情報がコンテンツに含まれて返ってきます。

ちなみに、Controller で疑似的に例外をスローというのは以下のようにしています。

イメージ説明

【追記】

質問者さんが下のコメント欄に書いた url の https://usign.shop/test.html を、自分の環境で試して Fiddler で要求・応答をキャプチャしたの画像を以下に貼っておきます。ブラウザは Chrome 78.0.3904.87 です。

イメージ説明

#77 がサイズ 206 KB (211,951 バイト) の .jpg 画像で応答は HTTP/1.1 413 Request Entity Too Large となり失敗。

#85 がサイズ 41.8 KB (42,856 バイト)の .jpg 画像で応答は HTTP/1.1 200 OK となり成功。

【追記2】

SSL だけでそういう問題が出るとすると FAQ レベルの話&周知の事例なのに、そうでもなさそうなのが不思議だったのですが、client certificate も絡んだ問題なのかもしれません。

以下の記事の回答で黄色のバックグラウンドとなっている部分が IIS Express を使った時のエラーメッセージのようです。

IIS randomly returns 413 Request Entity Too Large when uploading large files and using TLS
https://serverfault.com/questions/900211/iis-randomly-returns-413-request-entity-too-large-when-uploading-large-files-and

その中に:

Most likely causes: The Web server cannot service the request because it is trying to negotiate a client certificate but the request entity is too large.

If using client certificates, try: Increasing system.webServer/serverRuntime@uploadReadAheadSize

・・・とあります。

実際、質問者さんのサイトは client certificate を要求しているようです。以下の画像は Fiddler 経由でアクセスしているときに表示されたものです。そう書いてありますね。

イメージ説明

ちなみに、自分の環境の Visual Studio Community 2015 で IIS Express で SSL 通信を利用する設定にして(設定方法は下記参照)試してみましたが、uploadReadAheadSize はデフォルトのままで問題なしでした。

IIS Express で SSL 通信
http://surferonwww.info/BlogEngine/post/2018/09/09/ssl-communication-on-iis-express.aspx

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/11 07:40

    要求を出している先は http ハンドラで、wcf ではないので wcf の制限は関係なさそうです。

    ssl を使っていると 413 エラーになって UploadReadAheadSize の設定で解決できるという Microsoft の記事がありました。ssl 使ってますよね?

    キャンセル

  • 2019/11/11 08:54

    ありがとうございます。
    はい、SSLをつかっています。先月にSSL化を実施したところなので、UploadReadAheadSizeの設定が必要になったということなんですね。。同じサーバで複数ドメインを使用しており、同じくSSL化したので合わせて確認しておきたいと思います!
    本当にお力添えいただきありがとうございました。

    キャンセル

  • 2019/11/11 11:23

    SSL だけでなく client certificate も絡んだ問題なのかもしれません。そのことを回答欄に追記しておきます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる