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

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

ただいまの
回答率

91.37%

  • PHP

    15140questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • HTML

    6155questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • jQuery

    4884questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • Ajax

    804questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

jqueryのajaxのフォームで添付ファイルが送信できない

解決済

回答 1

投稿 2017/12/03 00:55

  • 評価
  • クリップ 0
  • VIEW 78

nosonosolife

score 23

jqueryのajaxとphpを使用して添付ファイル付きメールを送信するフォームを作成したのですが、「正しく送信されました」とポップアップが出たにもかかわらずメールが送信されていません。
原因は何でしょうか。ご提示よろしくお願いいたします。

            <form enctype="multipart/form-data" action="php/hoge.php" method="post" name="mailform">
            <input type="hidden" name="MAX_FILE_SIZE" value="8000000">
                <dl>
                    <dt>ペンネーム</dt>
                    <dd><input type="text" size="30" name="Penname" /></dd>
                </dl>
                <dl>
                    <dt>都道府県</dt>
                    <dd>
                <select name="Pref">
<option value="未選択" selected>未選択
<option value="北海道">北海道
<option value="青森県">青森県
<option value="岩手県">岩手県
<option value="宮城県">宮城県
<option value="秋田県">秋田県
<option value="山形県">山形県
<option value="福島県">福島県
<option value="茨城県">茨城県
<option value="栃木県">栃木県
<option value="群馬県">群馬県
<option value="埼玉県">埼玉県
<option value="千葉県">千葉県
<option value="東京都">東京都
<option value="神奈川県">神奈川県
<option value="新潟県">新潟県
<option value="富山県">富山県
<option value="石川県">石川県
<option value="福井県">福井県
<option value="山梨県">山梨県
<option value="長野県">長野県
<option value="岐阜県">岐阜県
<option value="静岡県">静岡県
<option value="愛知県">愛知県
<option value="三重県">三重県
<option value="滋賀県">滋賀県
<option value="京都府">京都府
<option value="大阪府">大阪府
<option value="兵庫県">兵庫県
<option value="奈良県">奈良県
<option value="和歌山県">和歌山県
<option value="鳥取県">鳥取県
<option value="島根県">島根県
<option value="岡山県">岡山県
<option value="広島県">広島県
<option value="山口県">山口県
<option value="徳島県">徳島県
<option value="香川県">香川県
<option value="愛媛県">愛媛県
<option value="高知県">高知県
<option value="福岡県">福岡県
<option value="佐賀県">佐賀県
<option value="長崎県">長崎県
<option value="熊本県">熊本県
<option value="大分県">大分県
<option value="宮崎県">宮崎県
<option value="鹿児島県">鹿児島県
<option value="沖縄県">沖縄県
</select>
                    </dd>
                </dl>
                <dl>
                    <dt>メッセージ</dt>
                    <dd><textarea name="Message" cols="40" rows="6" wrap="off"></textarea></dd>
                </dl>
                <dl>
                    <dt>添付ファイル</dt>
                    <dd><input type="file" name="upfile" size="30"></dd>
                </dl>
                <input id="submit" type="submit" name="submit" value=" 送信 ">
            </form>
$(document).ready(function(){
    $("#mailform form").submit(function(event) {
    // HTMLでの送信をキャンセル
        event.preventDefault();

        var errMsg      = "";
        var isFormError = false;

        var tmpName  = "";
        var tmpMessage  = "";

        var buf = "";
        buf = $(this).find("[name = Penname]").val().replace(/\s+$/,"");
        if(buf == ""){
            errMsg += "ペンネームを入力してください\n";
            isFormError = true;
        }
        else if(buf.length > 20){
            errMsg += "ペンネームが長すぎます("+buf.length+"文字))\n";
            isFormError = true;
        }
        else{
            tmpName = buf;
        }

        buf = $(this).find("[name = Message]").val().replace(/\s+$/,"");
        if(buf ==""){
            errMsg += "メッセージを入力してください\n";
            isFormError = true;
        }
        else if(buf.length > 10000){
            errMsg += "メッセージが長すぎます 現在("+buf.length+"文字)\n";
            isFormError = true;
        }
        else{
            tmpMessage = buf;
        }

        if(isFormError == true){
            alert(errMsg);
            event.preventDefault();
            return false;
        }
        else if(window.confirm("この内容で送信します。")==true){
            // 無駄な空白を省いた物(telは全角半角変換も有り)
            $(this).find("[name = Name]").val(tmpName);
            $(this).find("[name = Message]").val(tmpMessage);

            $.ajax({
                type: $(this).attr('method'),
                url: $(this).attr('action'),
                data: $(this).serialize(),
                timeout: 10000,  // 単位はミリ秒
                processData: false,
                contentType: false,

                // 送信前
                beforeSend: function(xhr, settings) {
                    // ボタンを無効化し、二重送信を防止
                     $(this).find('submit').attr('disabled', true);
                },
                // 応答後
                complete: function(xhr, textStatus) {
                    // ボタンを有効化し、再送信を許可
                    $(this).find('submit').attr('disabled', false);
                },
                success: function(result, textStatus, xhr) {
                    alert('正しく送信されました。');
                    $(this).find("[name = Message]").val(''); 
                },
                // 通信失敗時の処理
                error: function(xhr, textStatus, error) {
                    alert('正しく送信されませんでした。\n' + error );
                }
            });

            return false;
        }
        return false;
    });
});
<?php

//Ajax通信ではなく、直接URLを叩かれた場合はエラーメッセージを表示
if (
    !(isset($_SERVER["HTTP_X_REQUESTED_WITH"]) && strtolower($_SERVER["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest") 
    && (!empty($_SERVER["SCRIPT_FILENAME"]) && "hoge.php" === basename($_SERVER["SCRIPT_FILENAME"]))
    ) 
{
    header("HTTP/1.1 404 Not Found");
}
// SETUP
mb_language( "japanese" );
mb_internal_encoding( "UTF-8" );
date_default_timezone_set("Asia/Tokyo");

$field_subject = $_POST["Subject"];
$field_penname = $_POST["Penname"];
$field_pref = $_POST["Pref"];
$field_message = $_POST["Message"];
$date = date("Y/m/d D H:i:s");

$to_email = "test@hoge.com";
$from_email= "test-from@hoge.com";
$from_name = "test-from@hoge.com";
$subject = $field_subject." 投稿通知";

$body = "[投稿日時] ".$date."\n";
$body .= "ペンネーム : ".$field_penname."\n";
$body .= "都道府県 : ".$field_pref."\n";
$body .= "\n";
$body .= "■メッセージ"."\n";
$body .= $field_message."\n";

if (is_uploaded_file($_FILES['upfile']['tmp_name'])) {
    // 未定義である・複数ファイルである・$_FILES Corruption 攻撃を受けた
    // どれかに該当していれば不正なパラメータとして処理する
    if (!isset($_FILES['upfile']['error']) || !is_int($_FILES['upfile']['error'])) {
        header("HTTP/1.1 503 Service Unavailable");
        return;
    }

    // $_FILES['upfile']['error'] の値を確認
    switch ($_FILES['upfile']['error']) {
        case UPLOAD_ERR_OK: // OK
            break;
        case UPLOAD_ERR_NO_FILE:   // ファイル未選択
            header("HTTP/1.1 503 Service Unavailable");
            return;
        case UPLOAD_ERR_INI_SIZE:  // php.ini定義の最大サイズ超過
        case UPLOAD_ERR_FORM_SIZE: // フォーム定義の最大サイズ超過 (設定した場合のみ)
            header("HTTP/1.1 503 Service Unavailable");
            return;
        default:
            header("HTTP/1.1 503 Service Unavailable");
            return;
    }

    // ここで定義するサイズ上限のオーバーチェック
    // (必要がある場合のみ)
    if ($_FILES['upfile']['size'] > 8000000) {
        header("HTTP/1.1 503 Service Unavailable");
        return;
    }

    // $_FILES['upfile']['mime']の値はブラウザ側で偽装可能なので
    // MIMEタイプに対応する拡張子を自前で取得する
    if (!$ext = array_search(
        mime_content_type($_FILES['upfile']['tmp_name']),
        array(
            'gif' => 'image/gif',
            'jpg' => 'image/jpeg',
            'png' => 'image/png',
            'pdf' => 'application/pdf',
        ),
        true
    )) {
        header("HTTP/1.1 503 Service Unavailable");
        return;
    }

    // ファイルデータからSHA-1ハッシュを取ってファイル名を決定し,保存する
    if (!move_uploaded_file(
        $_FILES['upfile']['tmp_name'],
        $path = sprintf('./upload/%s.%s',
            sha1_file($_FILES['upfile']['tmp_name']),
            $ext
        )
    )) {
        header("HTTP/1.1 503 Service Unavailable");
        return;
    }

    // ファイルのパーミッションを確実に0644に設定する
    chmod($path, 0644);
}
// send the email
if (!empty($field_penname)) {
    sendmail_jpn($to_email, $subject, $body, $from_email,$from_name, $path);
}
sleep(1);

//関数-----------------------------------

function sendmail_jpn($to, $subject, $message, $from_email,$from_name, $filepath)
{
if (!empty($filepath)) {
$file_ext = pathinfo($filepath, PATHINFO_EXTENSION);     
    if ($file_ext == "pdf") {
        $mime_type = "application/pdf";
    } elseif ($file_ext == "jpg" || $file_ext == "jpeg") {
        $mime_type = "image/jpeg";
    } elseif ($file_ext == "gif") {
        $mime_type = "image/gif";
    } elseif ($file_ext == "png") {
        $mime_type = "image/png";
    } else {
        $mime_type = "application/octet-stream";
    }

// 添付ファイルのエンコード
$filename = basename( $filepath );

// マルチパートなので、パートの区切り文字列を指定
$boundary = "----=_Boundary_" . uniqid(rand(1000,9999) . "_") . "_";
}else {
$boundary = null;
}

// 件名のエンコード
$subject = mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8");
$subject = mb_encode_mimeheader_ex($subject);

// 本文のエンコード
$message = mb_convert_encoding($message, "ISO-2022-JP", "UTF-8");

// toをエンコード
// $to = mb_convert_encoding($mail["to"]["name"], "SJIS", "UTF-8");
$to = "=?ISO-2022-JP?B?" . base64_encode($to) . "?= <" . $to . ">";

// fromをエンコード
// $from = mb_convert_encoding($mail["from"]["name"], "SJIS", "UTF-8");
$from = "=?ISO-2022-JP?B?" . base64_encode($from_name) . "?= <" . $from_email . ">";

if (!empty($filepath)) {
// 添付ファイルのエンコード
$filename = mb_convert_encoding($filename, "ISO-2022-JP", "UTF-8");
$filename = "=?ISO-2022-JP?B?" . base64_encode($filename) . "?=";
}

// ヘッダーの指定
$head = "";
$head .= "From: {$from}\n";
$head .= "MIME-Version: 1.0\n";
if (empty($filepath)) {
$head .= "Content-Type: text/plain; charset=ISO-2022-JP;" .
"Content-Transfer-Encoding: 7bit\n";
}else {
$head .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\n";
}
$head .= "Content-Transfer-Encoding: 7bit";

$body = "";

// 本文
if (!empty($filepath)) {
$body .= "--{$boundary}\n";
$body .= "Content-Type: text/plain; charset=ISO-2022-JP;" .
"Content-Transfer-Encoding: 7bit\n";
$body .= "\n";
}
$body .= "{$message}\n";
$body .= "\n";

if (!empty($filepath)) {
// 添付ファイルの処理
$body .= "--{$boundary}\n";
$body .= "Content-Type: {$mime_type}; name=\"{$filename}\"\n" .
"Content-Transfer-Encoding: base64\n" .
"Content-Disposition: attachment; filename=\"{$filename}\"\n";
$body .= "\n";

$fp = fopen( $filepath, "r" ) or die("Error on mailing. (attachment file cannot open)");
$contents = fread( $fp, filesize($filepath) );
fclose( $fp );
$f_encoded = chunk_split(base64_encode($contents)); //添付ファイルをbase64エンコードする
$body .= "{$f_encoded}\n";
$body .= "\n";
}

if (mail($to, $subject, $body, $head)) {
echo "sendmail_jpn : OK.";
} else {
echo "sendmail_jpn : FAILURE.";
}
}

// mb_encode_mimeheaderのバグ対策用
function mb_encode_mimeheader_ex($text, $split_count = 34) {
$position = 0;
$encorded = "";

while ($position < mb_strlen($text, "ISO-2022-JP")) {
if ($encorded != "") {
$encorded .= "\r\n ";
}
$output_temp = mb_strimwidth($text, $position, $split_count, "", "ISO-2022-JP");
$position = $position + mb_strlen($output_temp, "ISO-2022-JP");
$encorded .= "=?ISO-2022-JP?B?" . base64_encode($output_temp) . "?=";
}

return $encorded;
}
?>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • nosonosolife

    2017/12/03 01:44

    サーバーは「xrea」、phpのバージョンは71です。

    キャンセル

  • Kosuke_Shibuya

    2017/12/03 01:45

    それであればxreaの公式サポートページに書かれているはずです。

    キャンセル

  • nosonosolife

    2017/12/03 02:05

    確認したところ、サーバーの種類は「Apache」でした。「PHPのインストール方法」については分かりませんでした。

    キャンセル

回答 1

checkベストアンサー

+2

var form = $('#mailform form').get()[0];
var data = new FormData( form );

シリアライズじゃなくこっちでどうだい?
    

投稿 2017/12/03 10:22

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/03 18:03

    ご提示していただいたコードをもとに書き換えたところ上手く動きました。
    ご回答ありがとうございました。

    キャンセル

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

ただいまの回答率

91.37%

関連した質問

同じタグがついた質問を見る

  • PHP

    15140questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • HTML

    6155questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • jQuery

    4884questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • Ajax

    804questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。