XMLをPOSTリクエストで送信する方法|完全ガイド

プログラミング・IT

Web APIを使った開発をしていると、「XMLデータをサーバーに送信したい」という場面に出くわすことがありますよね。

JSONが主流になった今でも、SOAP APIや一部のレガシーシステムでは、XMLフォーマットでのデータ送信が必要なケースが残っています。

この記事では、XMLデータをHTTP POSTリクエストで送信する方法を、基礎から実践まで詳しく解説します。curl、Python、JavaScript、Javaなど、様々なツールや言語での実装例も紹介しますので、あなたの環境に合った方法が見つかるはずですよ!


スポンサーリンク
  1. XMLをPOSTで送る基本的な仕組み
    1. HTTP POSTリクエストとは
    2. XMLをPOSTで送る時の重要なポイント
  2. curlコマンドでXMLをPOSTする
    1. 基本的なcurlコマンド
    2. ファイルからXMLを読み込む
    3. レスポンスを確認する
    4. 認証が必要な場合
  3. PythonでXMLをPOSTする
    1. requestsライブラリを使う方法
    2. ファイルからXMLを読み込む
    3. ElementTreeでXMLを生成してPOSTする
    4. エラーハンドリングを追加
  4. JavaScriptでXMLをPOSTする
    1. Fetch APIを使う方法(ブラウザ)
    2. async/awaitを使った書き方
    3. XMLHttpRequestを使う方法(古いブラウザ対応)
    4. Node.jsでaxiosを使う方法
  5. JavaでXMLをPOSTする
    1. HttpClientを使う方法(Java 11以降)
    2. Apache HttpClientを使う方法
  6. PHPでXMLをPOSTする
    1. cURLを使う方法
    2. file_get_contentsを使う方法
  7. SOAP APIへのXMLリクエスト
    1. SOAP リクエストの構造
    2. curlでSOAPリクエストを送る
    3. PythonでSOAPリクエスト
  8. Content-Typeの使い分け
    1. application/xml vs text/xml
    2. その他の特殊なContent-Type
    3. 使い分けの目安
  9. よくあるエラーと対処法
    1. エラー1:415 Unsupported Media Type
    2. エラー2:400 Bad Request(XML解析エラー)
    3. エラー3:文字化け
    4. エラー4:タイムアウト
    5. エラー5:CORS エラー(ブラウザから送信時)
  10. セキュリティ上の注意点
    1. 1. HTTPSを使う
    2. 2. XML外部エンティティ攻撃(XXE)対策
    3. 3. 入力値のバリデーション
    4. 4. 認証情報の保護
  11. デバッグとテストのコツ
    1. リクエストの内容を確認する
    2. Postmanを使う
    3. ローカルサーバーでテスト
  12. まとめ:XMLをPOSTする実践ガイド

XMLをPOSTで送る基本的な仕組み

まず、XMLデータをPOSTリクエストで送る際の基本を理解しましょう。

HTTP POSTリクエストとは

HTTP POSTは、クライアント(ブラウザやプログラム)からサーバーにデータを送信するための方法です。

GETリクエストと違って、POSTでは:

  • URLではなく、リクエストボディにデータを含める
  • 大量のデータを送れる
  • データがURL履歴に残らない

XMLをPOSTで送る時の重要なポイント

XMLデータをPOSTする際、特に重要なのが以下の3つです:

1. Content-Typeヘッダー
サーバーに「XMLデータを送っていますよ」と伝えるため、適切なContent-Typeを設定します。

Content-Type: application/xml

または:

Content-Type: text/xml

2. リクエストボディにXMLを配置
送信したいXMLデータを、HTTPリクエストのボディ部分に含めます。

3. 文字エンコーディング
日本語などを含む場合、UTF-8エンコーディングを明示します。

Content-Type: application/xml; charset=UTF-8

curlコマンドでXMLをPOSTする

最もシンプルで、動作確認にも便利な方法から始めましょう。

基本的なcurlコマンド

curl -X POST \
  -H "Content-Type: application/xml" \
  -d '<user><name>田中太郎</name><email>tanaka@example.com</email></user>' \
  https://api.example.com/users

オプションの説明:

  • -X POST:POSTメソッドを指定
  • -H:ヘッダーを追加
  • -d:送信するデータ(ここにXML)
  • 最後がリクエスト先のURL

ファイルからXMLを読み込む

XMLが長い場合、ファイルから読み込む方が便利です。

curl -X POST \
  -H "Content-Type: application/xml" \
  -d @request.xml \
  https://api.example.com/users

@を付けることで、ファイルの内容を読み込めます。

request.xml の例:

<?xml version="1.0" encoding="UTF-8"?>
<user>
  <name>田中太郎</name>
  <email>tanaka@example.com</email>
  <age>30</age>
</user>

レスポンスを確認する

curl -X POST \
  -H "Content-Type: application/xml" \
  -d @request.xml \
  -v \
  https://api.example.com/users

-v(verbose)オプションを付けると、リクエストとレスポンスの詳細が表示されます。

認証が必要な場合

Basic認証が必要なAPIの場合:

curl -X POST \
  -H "Content-Type: application/xml" \
  -u username:password \
  -d @request.xml \
  https://api.example.com/users

Bearer トークン認証の場合:

curl -X POST \
  -H "Content-Type: application/xml" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -d @request.xml \
  https://api.example.com/users

PythonでXMLをPOSTする

Pythonでの実装方法を見ていきましょう。

requestsライブラリを使う方法

最も一般的で簡単な方法です。

import requests

# XMLデータを文字列として定義
xml_data = '''<?xml version="1.0" encoding="UTF-8"?>
<user>
  <name>田中太郎</name>
  <email>tanaka@example.com</email>
  <age>30</age>
</user>'''

# ヘッダーを設定
headers = {
    'Content-Type': 'application/xml; charset=UTF-8'
}

# POSTリクエストを送信
response = requests.post(
    'https://api.example.com/users',
    data=xml_data.encode('utf-8'),
    headers=headers
)

# レスポンスを確認
print(f'ステータスコード: {response.status_code}')
print(f'レスポンス: {response.text}')

ファイルからXMLを読み込む

import requests

# XMLファイルを読み込む
with open('request.xml', 'r', encoding='utf-8') as f:
    xml_data = f.read()

headers = {
    'Content-Type': 'application/xml; charset=UTF-8'
}

response = requests.post(
    'https://api.example.com/users',
    data=xml_data.encode('utf-8'),
    headers=headers
)

print(response.text)

ElementTreeでXMLを生成してPOSTする

XMLを動的に生成する場合:

import requests
import xml.etree.ElementTree as ET

# XMLを動的に生成
root = ET.Element('user')
name = ET.SubElement(root, 'name')
name.text = '田中太郎'
email = ET.SubElement(root, 'email')
email.text = 'tanaka@example.com'
age = ET.SubElement(root, 'age')
age.text = '30'

# XML宣言を含む文字列に変換
xml_data = ET.tostring(root, encoding='utf-8', xml_declaration=True)

headers = {
    'Content-Type': 'application/xml; charset=UTF-8'
}

response = requests.post(
    'https://api.example.com/users',
    data=xml_data,
    headers=headers
)

print(response.status_code)

エラーハンドリングを追加

import requests

xml_data = '''<?xml version="1.0" encoding="UTF-8"?>
<user>
  <name>田中太郎</name>
  <email>tanaka@example.com</email>
</user>'''

headers = {
    'Content-Type': 'application/xml; charset=UTF-8'
}

try:
    response = requests.post(
        'https://api.example.com/users',
        data=xml_data.encode('utf-8'),
        headers=headers,
        timeout=10  # タイムアウトを10秒に設定
    )

    # HTTPエラーをチェック
    response.raise_for_status()

    print(f'成功: {response.text}')

except requests.exceptions.HTTPError as e:
    print(f'HTTPエラー: {e}')
except requests.exceptions.Timeout:
    print('タイムアウトしました')
except requests.exceptions.RequestException as e:
    print(f'リクエストエラー: {e}')

JavaScriptでXMLをPOSTする

ブラウザやNode.jsでの実装方法を紹介します。

Fetch APIを使う方法(ブラウザ)

モダンなブラウザで使える方法です。

const xmlData = `<?xml version="1.0" encoding="UTF-8"?>
<user>
  <name>田中太郎</name>
  <email>tanaka@example.com</email>
  <age>30</age>
</user>`;

fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/xml; charset=UTF-8'
  },
  body: xmlData
})
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTPエラー: ${response.status}`);
    }
    return response.text();
  })
  .then(data => {
    console.log('成功:', data);
  })
  .catch(error => {
    console.error('エラー:', error);
  });

async/awaitを使った書き方

async function sendXML() {
  const xmlData = `<?xml version="1.0" encoding="UTF-8"?>
  <user>
    <name>田中太郎</name>
    <email>tanaka@example.com</email>
  </user>`;

  try {
    const response = await fetch('https://api.example.com/users', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/xml; charset=UTF-8'
      },
      body: xmlData
    });

    if (!response.ok) {
      throw new Error(`HTTPエラー: ${response.status}`);
    }

    const result = await response.text();
    console.log('成功:', result);

  } catch (error) {
    console.error('エラー:', error);
  }
}

sendXML();

XMLHttpRequestを使う方法(古いブラウザ対応)

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/users', true);
xhr.setRequestHeader('Content-Type', 'application/xml; charset=UTF-8');

xhr.onload = function() {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log('成功:', xhr.responseText);
  } else {
    console.error('エラー:', xhr.status);
  }
};

xhr.onerror = function() {
  console.error('ネットワークエラー');
};

const xmlData = `<?xml version="1.0" encoding="UTF-8"?>
<user>
  <name>田中太郎</name>
  <email>tanaka@example.com</email>
</user>`;

xhr.send(xmlData);

Node.jsでaxiosを使う方法

const axios = require('axios');

const xmlData = `<?xml version="1.0" encoding="UTF-8"?>
<user>
  <name>田中太郎</name>
  <email>tanaka@example.com</email>
  <age>30</age>
</user>`;

axios.post('https://api.example.com/users', xmlData, {
  headers: {
    'Content-Type': 'application/xml; charset=UTF-8'
  }
})
  .then(response => {
    console.log('ステータス:', response.status);
    console.log('データ:', response.data);
  })
  .catch(error => {
    console.error('エラー:', error.message);
  });

JavaでXMLをPOSTする

Java環境での実装例です。

HttpClientを使う方法(Java 11以降)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class XMLPostExample {
    public static void main(String[] args) throws Exception {
        String xmlData = """
            <?xml version="1.0" encoding="UTF-8"?>
            <user>
              <name>田中太郎</name>
              <email>tanaka@example.com</email>
              <age>30</age>
            </user>
            """;

        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.example.com/users"))
            .header("Content-Type", "application/xml; charset=UTF-8")
            .POST(HttpRequest.BodyPublishers.ofString(xmlData))
            .build();

        HttpResponse<String> response = client.send(
            request,
            HttpResponse.BodyHandlers.ofString()
        );

        System.out.println("ステータスコード: " + response.statusCode());
        System.out.println("レスポンス: " + response.body());
    }
}

Apache HttpClientを使う方法

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class XMLPostExample {
    public static void main(String[] args) {
        String xmlData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                        "<user>" +
                        "<name>田中太郎</name>" +
                        "<email>tanaka@example.com</email>" +
                        "</user>";

        try (CloseableHttpClient client = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost("https://api.example.com/users");

            // XMLデータを設定
            StringEntity entity = new StringEntity(xmlData, "UTF-8");
            entity.setContentType("application/xml; charset=UTF-8");
            httpPost.setEntity(entity);

            // リクエストを送信
            try (CloseableHttpResponse response = client.execute(httpPost)) {
                System.out.println("ステータス: " + response.getStatusLine());
                String responseBody = EntityUtils.toString(response.getEntity());
                System.out.println("レスポンス: " + responseBody);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

PHPでXMLをPOSTする

PHP環境での実装方法です。

cURLを使う方法

<?php
$xmlData = '<?xml version="1.0" encoding="UTF-8"?>
<user>
  <name>田中太郎</name>
  <email>tanaka@example.com</email>
  <age>30</age>
</user>';

$ch = curl_init('https://api.example.com/users');

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/xml; charset=UTF-8',
    'Content-Length: ' . strlen($xmlData)
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($response === false) {
    echo 'cURLエラー: ' . curl_error($ch);
} else {
    echo "ステータスコード: $httpCode\n";
    echo "レスポンス: $response\n";
}

curl_close($ch);
?>

file_get_contentsを使う方法

<?php
$xmlData = '<?xml version="1.0" encoding="UTF-8"?>
<user>
  <name>田中太郎</name>
  <email>tanaka@example.com</email>
</user>';

$options = [
    'http' => [
        'method' => 'POST',
        'header' => 'Content-Type: application/xml; charset=UTF-8',
        'content' => $xmlData
    ]
];

$context = stream_context_create($options);
$response = file_get_contents('https://api.example.com/users', false, $context);

if ($response === false) {
    echo "エラーが発生しました\n";
} else {
    echo "レスポンス: $response\n";
}
?>

SOAP APIへのXMLリクエスト

SOAPは、XMLベースのWebサービスプロトコルです。

SOAP リクエストの構造

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <!-- ヘッダー情報(認証など) -->
  </soap:Header>
  <soap:Body>
    <GetUserInfo xmlns="http://example.com/services">
      <userId>12345</userId>
    </GetUserInfo>
  </soap:Body>
</soap:Envelope>

curlでSOAPリクエストを送る

curl -X POST \
  -H "Content-Type: text/xml; charset=UTF-8" \
  -H "SOAPAction: http://example.com/services/GetUserInfo" \
  -d @soap-request.xml \
  https://api.example.com/soap

soap-request.xml:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:ser="http://example.com/services">
  <soap:Header/>
  <soap:Body>
    <ser:GetUserInfo>
      <ser:userId>12345</ser:userId>
    </ser:GetUserInfo>
  </soap:Body>
</soap:Envelope>

PythonでSOAPリクエスト

import requests

soap_request = '''<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:ser="http://example.com/services">
  <soap:Body>
    <ser:GetUserInfo>
      <ser:userId>12345</ser:userId>
    </ser:GetUserInfo>
  </soap:Body>
</soap:Envelope>'''

headers = {
    'Content-Type': 'text/xml; charset=UTF-8',
    'SOAPAction': 'http://example.com/services/GetUserInfo'
}

response = requests.post(
    'https://api.example.com/soap',
    data=soap_request.encode('utf-8'),
    headers=headers
)

print(response.text)

Content-Typeの使い分け

XMLをPOSTする際、どのContent-Typeを使うべきか迷うことがあります。

application/xml vs text/xml

application/xml(推奨)

  • 現代的な標準
  • UTF-8以外の文字コードも柔軟に扱える
  • REST APIで一般的
Content-Type: application/xml; charset=UTF-8

text/xml

  • 古い標準
  • デフォルトの文字コードがUS-ASCII
  • SOAP APIで使われることが多い
Content-Type: text/xml; charset=UTF-8

その他の特殊なContent-Type

application/soap+xml
SOAP 1.2専用:

Content-Type: application/soap+xml; charset=UTF-8

application/xhtml+xml
XHTMLドキュメントの場合:

Content-Type: application/xhtml+xml; charset=UTF-8

使い分けの目安

API種別推奨Content-Type
REST APIapplication/xml
SOAP 1.1text/xml
SOAP 1.2application/soap+xml
XHTMLapplication/xhtml+xml

よくあるエラーと対処法

XMLをPOSTする際によく遭遇するエラーと解決方法です。

エラー1:415 Unsupported Media Type

原因:
Content-Typeヘッダーが正しく設定されていません。

対処法:

# 悪い例
curl -X POST -d @request.xml https://api.example.com/users

# 良い例
curl -X POST \
  -H "Content-Type: application/xml" \
  -d @request.xml \
  https://api.example.com/users

エラー2:400 Bad Request(XML解析エラー)

原因:
送信したXMLの構文が間違っています。

対処法:
XMLの構文を確認:

# XMLLintで構文チェック
xmllint --noout request.xml

よくある間違い:

  • タグの閉じ忘れ
  • XML宣言の誤り
  • 特殊文字のエスケープ漏れ

エラー3:文字化け

原因:
文字エンコーディングが正しく処理されていません。

対処法:

# Pythonの場合、明示的にUTF-8でエンコード
xml_data = '<?xml version="1.0" encoding="UTF-8"?><user>...</user>'
response = requests.post(
    url,
    data=xml_data.encode('utf-8'),  # 明示的にエンコード
    headers={'Content-Type': 'application/xml; charset=UTF-8'}
)

エラー4:タイムアウト

原因:
サーバーの応答が遅いか、ネットワークの問題があります。

対処法:

# タイムアウトを設定
response = requests.post(
    url,
    data=xml_data,
    headers=headers,
    timeout=30  # 30秒でタイムアウト
)

エラー5:CORS エラー(ブラウザから送信時)

原因:
ブラウザのセキュリティポリシーでブロックされています。

対処法:

  • サーバー側でCORSヘッダーを設定してもらう
  • プロキシサーバーを経由する
  • サーバーサイドから送信する(ブラウザを経由しない)

セキュリティ上の注意点

XMLをPOSTする際のセキュリティ対策です。

1. HTTPSを使う

機密情報を含むXMLは、必ずHTTPSで送信しましょう。

# 良い例(HTTPS)
curl -X POST https://api.example.com/users

# 悪い例(HTTP)
curl -X POST http://api.example.com/users

2. XML外部エンティティ攻撃(XXE)対策

悪意のあるXMLを送られないよう、サーバー側で対策が必要です。

危険なXMLの例:

<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<user>
  <name>&xxe;</name>
</user>

対策(Pythonの例):

import xml.etree.ElementTree as ET

# 外部エンティティを無効化
ET.XMLParser(resolve_entities=False)

3. 入力値のバリデーション

送信するXMLデータには、必ずバリデーションを行いましょう。

# 特殊文字をエスケープ
import xml.sax.saxutils as saxutils

user_input = '<script>alert("XSS")</script>'
escaped_input = saxutils.escape(user_input)
# 結果: &lt;script&gt;alert("XSS")&lt;/script&gt;

4. 認証情報の保護

APIキーやトークンは、環境変数設定ファイルで管理しましょう。

import os

api_key = os.environ.get('API_KEY')

headers = {
    'Content-Type': 'application/xml',
    'Authorization': f'Bearer {api_key}'
}

デバッグとテストのコツ

XMLリクエストのデバッグに役立つテクニックです。

リクエストの内容を確認する

# curlで詳細を表示
curl -v -X POST \
  -H "Content-Type: application/xml" \
  -d @request.xml \
  https://api.example.com/users

-vオプションで、送信したヘッダーやボディが表示されます。

Postmanを使う

Postmanは、APIテストに便利なツールです。

  1. 新しいリクエストを作成
  2. メソッドを「POST」に設定
  3. 「Body」タブで「raw」を選択
  4. ドロップダウンから「XML」を選択
  5. XMLデータを入力
  6. 「Send」をクリック

ローカルサーバーでテスト

本番環境に送る前に、ローカルでテストしましょう。

Pythonで簡単なテストサーバー:

from flask import Flask, request

app = Flask(__name__)

@app.route('/test', methods=['POST'])
def test():
    xml_data = request.data.decode('utf-8')
    print('受信したXML:')
    print(xml_data)
    return '<response>OK</response>', 200

if __name__ == '__main__':
    app.run(port=5000)

まとめ:XMLをPOSTする実践ガイド

XMLをPOSTリクエストで送信する方法をまとめます。

基本的な手順:

  1. Content-Typeヘッダーを設定
  • application/xml; charset=UTF-8(推奨)
  • text/xml; charset=UTF-8(SOAP)
  1. リクエストボディにXMLを配置
  • 文字列として直接指定
  • ファイルから読み込み
  1. HTTPSで送信
  • 機密情報はHTTPSで保護

各ツール・言語での実装:

  • curl: -H "Content-Type: application/xml" -d @file.xml
  • Python: requests.post(url, data=xml_data, headers=...)
  • JavaScript: fetch(url, {method: 'POST', body: xmlData, ...})
  • Java: HttpRequest.POST(HttpRequest.BodyPublishers.ofString(xmlData))
  • PHP: curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData)

Content-Typeの使い分け:

  • REST API → application/xml
  • SOAP 1.1 → text/xml
  • SOAP 1.2 → application/soap+xml

セキュリティ対策:

  • HTTPSを使用
  • XXE攻撃対策
  • 入力値のバリデーション
  • 認証情報の適切な管理

トラブル時のチェックポイント:

  • Content-Typeヘッダーは正しいか
  • XMLの構文にエラーはないか
  • 文字エンコーディングは適切か
  • タイムアウト設定は十分か

XMLをPOSTする処理は、基本的な仕組みさえ理解すれば、どの言語やツールでも同じように実装できます。この記事で紹介した方法を参考に、あなたのプロジェクトに合った実装を選んでください!

まずはcurlで動作確認してから、本格的なプログラムに組み込むのがおすすめですよ。


関連キーワード: HTTP POST、XMLリクエスト、Content-Type、REST API、SOAP、curl、Python requests、JavaScript Fetch、Java HttpClient、PHP cURL、エンコーディング、セキュリティ、XXE、HTTPS、API連携

コメント

タイトルとURLをコピーしました