| (同じ利用者による、間の6版が非表示) | |||
| 101行目: | 101行目: | ||
== ソリューション == | == ソリューション == | ||
==== | ==== 方法 1 : static / readonly ==== | ||
<code>HttpClient</code>クラスは、<code>private</code>キーワードおよび<code>static</code>キーワードを指定したプロパティとして持つ必要がある。<br> | <code>HttpClient</code>クラスは、<code>private</code>キーワードおよび<code>static</code>キーワードを指定したプロパティとして持つ必要がある。<br> | ||
<br> | <br> | ||
| 107行目: | 107行目: | ||
HttpClientを使用した実装をする時は、インスタンスを静的変数(static)にして使用するとの記載がある。<br> | HttpClientを使用した実装をする時は、インスタンスを静的変数(static)にして使用するとの記載がある。<br> | ||
<br> | <br> | ||
まず、<code>HttpClient</code>クラスのオブジェクトを生成する。<br> | まず、<code>HttpClient</code>クラスのオブジェクトを生成する。<br> | ||
この時、タイムアウトの設定等はコンストラクタで行う必要がある。<br> | この時、タイムアウトの設定等はコンストラクタで行う必要がある。<br> | ||
| 145行目: | 144行目: | ||
また、1つの<code>HttpClient</code>クラスは1つのソケット(1つのホスト)として使用した方がよいため、<br> | また、1つの<code>HttpClient</code>クラスは1つのソケット(1つのホスト)として使用した方がよいため、<br> | ||
異なるホストにもリクエストを投げる場合は、別の<code>HttpClient</code>クラスのオブジェクトを生成する方がよい。<br> | 異なるホストにもリクエストを投げる場合は、別の<code>HttpClient</code>クラスのオブジェクトを生成する方がよい。<br> | ||
<br> | |||
==== 方法 2 : HttpClientFactory (単一のベースURI) ==== | |||
* 依存性注入 (DI) の設定 | |||
*: Host.CreateDefaultBuilderメソッドを使用して、.NETの標準的なDIコンテナを設定する。 | |||
*: サービスの登録はConfigureServicesメソッドで行う。 | |||
*: 異なるライフタイムスコープ (Transient, Scoped, Singleton) から適切なものを選択する。 | |||
<br> | |||
HttpClientFactoryでは、2つのパターンがある。<br> | |||
* 名前付きHttpClient | |||
*: services.AddHttpClient("github", ...) で登録する。 | |||
*: IHttpClientFactory.CreateClient("github")で取得する。 | |||
*: 同じ名前で登録されたクライアントは同じ設定を共有する。 | |||
*: <br> | |||
* 型付きHttpClient | |||
*: services.AddHttpClient<GitHubService>メソッドで登録する。 | |||
*: コンストラクタインジェクションで自動的に注入する。 | |||
*: サービスごとに特化した実装が可能になる。 | |||
<br> | |||
Nugetを使用して、以下に示すライブラリをインストールする。<br> | |||
* Microsoft.Extensions.Http | |||
* Microsoft.Extensions.Hosting | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
using System; | |||
using System.Threading.Tasks; | |||
using System.Net.Http; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Hosting; | |||
class Program | |||
{ | |||
static async Task Main(string[] args) | |||
{ | |||
// GenericHostを使用してアプリケーションを構築 | |||
// これにより、依存性注入、構成、ログ等の機能が利用可能になる | |||
var host = Host.CreateDefaultBuilder(args).ConfigureServices((context, services) => { | |||
// 方法 1 : 名前付きHttpClientを使用する場合 | |||
// 名前付きHttpClientの登録 | |||
// "github"という名前で、GitHubのAPIにアクセスするためのHttpClientを設定 | |||
services.AddHttpClient("github", client => { | |||
// ベースとなるURIを設定 | |||
client.BaseAddress = new Uri("https://api.github.com/"); | |||
// User-Agentヘッダを設定 (GitHubのAPIでは必須) | |||
client.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample"); | |||
}); | |||
// 方法 2 : 型付きHttpClientを使用する場合 | |||
// 型付きHttpClientの登録 | |||
// GitHubServiceクラスに特化したHttpClientを自動的に注入 | |||
services.AddHttpClient<GitHubService>(); | |||
// ExampleServiceをDIコンテナに登録 | |||
// TransientスコープでサービスをDIコンテナに登録(毎回新しいインスタンスが作成される) | |||
services.AddTransient<IExampleService, ExampleService>(); | |||
}).Build(); | |||
// DIコンテナからサービスを取得し、実行 | |||
var service = host.Services.GetRequiredService<IExampleService>(); | |||
await service.RunExample(); | |||
} | |||
} | |||
/// <summary> | |||
/// 型付きHttpClientを使用するサービスクラス | |||
/// GitHubのAPIに特化した操作を提供 | |||
/// </summary> | |||
public class GitHubService | |||
{ | |||
private readonly HttpClient _httpClient; | |||
// コンストラクタインジェクション | |||
// DIコンテナにより、設定済みのHttpClientが自動的に注入される | |||
public GitHubService(HttpClient client) | |||
{ | |||
_httpClient = client; | |||
// このHttpClientインスタンスに対する固有の設定 | |||
_httpClient.BaseAddress = new Uri("https://api.github.com/"); | |||
_httpClient.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample"); | |||
} | |||
/// <summary> | |||
/// GitHubのAPIからデータを取得する | |||
/// </summary> | |||
/// <returns>API応答の文字列</returns> | |||
public async Task<string> GetApiResponse() | |||
{ | |||
// dotnet/runtimeリポジトリの情報を取得 | |||
return await _httpClient.GetStringAsync("repos/dotnet/runtime"); | |||
} | |||
} | |||
/// <summary> | |||
/// サービスのインターフェース定義 | |||
/// 依存性の注入とテストを容易にするために使用 | |||
/// </summary> | |||
public interface IExampleService | |||
{ | |||
Task RunExample(); | |||
} | |||
/// <summary> | |||
/// HttpClientFactoryの使用例を示すサービスクラス | |||
/// 名前付きHttpClientと型付きHttpClientの両方の使用例を提供 | |||
/// </summary> | |||
public class ExampleService : IExampleService | |||
{ | |||
private readonly IHttpClientFactory _clientFactory; | |||
private readonly GitHubService _githubService; | |||
/// <summary> | |||
/// コンストラクタで依存関係を注入 | |||
/// </summary> | |||
/// <param name="clientFactory">HttpClientFactory - 名前付きクライアントの作成に使用</param> | |||
/// <param name="githubService">GitHubService - 型付きHttpClientの例として使用</param> | |||
public ExampleService(IHttpClientFactory clientFactory, GitHubService githubService) | |||
{ | |||
_clientFactory = clientFactory; | |||
_githubService = githubService; | |||
} | |||
/// <summary> | |||
/// HttpClientFactoryの両方の使用パターンを実演 | |||
/// </summary> | |||
public async Task RunExample() | |||
{ | |||
// 方法 1 : 名前付きHttpClientの使用例 | |||
try | |||
{ | |||
// "github"という名前で設定されたHttpClientを取得 | |||
var client = _clientFactory.CreateClient("github"); | |||
var response = await client.GetStringAsync("repos/dotnet/runtime"); | |||
Console.WriteLine("Named HttpClient Response:"); | |||
Console.WriteLine(response.Substring(0, 200) + "..."); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine($"Named client error: {ex.Message}"); | |||
} | |||
// // 方法 2 : 型付きHttpClientの使用例 | |||
try | |||
{ | |||
// 注入されたGitHubServiceを使用 | |||
var response = await _githubService.GetApiResponse(); | |||
Console.WriteLine("Typed HttpClient Response:"); | |||
Console.WriteLine(response.Substring(0, 200) + "..."); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine($"Typed client error: {ex.Message}"); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== 方法 3 : HttpClientFactory (複数のベースURI) ==== | |||
* 名前付きHttpClientを使用する方法 | |||
** メリット | |||
**: 個別の設定が容易 | |||
** デメリット | |||
**: 文字列ベースの名前指定 | |||
**: 型安全性が低い | |||
*: <br> | |||
* 型付きHttpClientを使用する方法 | |||
** メリット | |||
**: 型安全性が高い | |||
**: APIごとに特化した実装が可能 | |||
**: テストが容易 | |||
** デメリット | |||
**: クラス数が増加 | |||
**: 各APIに対して個別の実装が必要 | |||
*: <br> | |||
* 動的にベースURIを切り替える方法 | |||
** メリット | |||
**: 柔軟性が高い | |||
**: 設定ファイルでの管理が容易 | |||
**: 実行時の切り替えが可能 | |||
** デメリット | |||
**: 複雑な実装 | |||
<br> | |||
<syntaxhighlight lang="json"> | |||
# 動的なベースURI切り替えで使用 | |||
# appsettings.json | |||
{ | |||
"ApiSettings": { | |||
"BaseUrls": { | |||
"github": "https://api.github.com/", | |||
"weather": "https://api.weather.com/", | |||
"other": "https://api.other.com/" | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
using System; | |||
using System.Threading.Tasks; | |||
using System.Net.Http; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Hosting; | |||
class Program | |||
{ | |||
static async Task Main(string[] args) | |||
{ | |||
var host = Host.CreateDefaultBuilder(args).ConfigureServices((context, services) => { | |||
// 方法 1 : 異なる名前で複数のHttpClientを登録 | |||
services.AddHttpClient("github", client => { | |||
client.BaseAddress = new Uri("https://api.github.com/"); | |||
client.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample"); | |||
}); | |||
services.AddHttpClient("weather", client => { | |||
client.BaseAddress = new Uri("https://api.weather.com/"); | |||
client.DefaultRequestHeaders.Add("User-Agent", "Weather-Service"); | |||
}); | |||
// 方法 2 : 型付きHttpClientを各APIサービス用に登録 | |||
services.AddHttpClient<GitHubService>(); | |||
services.AddHttpClient<WeatherService>(); | |||
// 方法 3 : 設定情報を含むサービスを登録 | |||
services.Configure<ApiSettings>(context.Configuration.GetSection("ApiSettings")); | |||
services.AddHttpClient<MultiBaseUriService>(); | |||
services.AddTransient<IMultiApiService, MultiApiService>(); | |||
}).Build(); | |||
var service = host.Services.GetRequiredService<IMultiApiService>(); | |||
await service.RunExample(); | |||
} | |||
} | |||
// APIの設定を保持するクラス | |||
public class ApiSettings | |||
{ | |||
public Dictionary<string, string> BaseUrls { get; set; } = new(); | |||
} | |||
// 複数のベースURIを扱うサービス | |||
public class MultiBaseUriService | |||
{ | |||
private readonly HttpClient _httpClient; | |||
private readonly ApiSettings _settings; | |||
private readonly Dictionary<string, string> _baseUrls; | |||
public MultiBaseUriService(HttpClient client, IOptions<ApiSettings> settings) | |||
{ | |||
_httpClient = client; | |||
_settings = settings.Value; | |||
_baseUrls = _settings.BaseUrls; | |||
} | |||
public async Task<string> SendRequest(string apiKey, string endpoint) | |||
{ | |||
if (!_baseUrls.TryGetValue(apiKey, out var baseUrl)) | |||
{ | |||
throw new ArgumentException($"Unknown API key: {apiKey}"); | |||
} | |||
var fullUrl = new Uri(new Uri(baseUrl), endpoint); | |||
return await _httpClient.GetStringAsync(fullUrl); | |||
} | |||
} | |||
// GithubのAPI用サービス | |||
public class GitHubService | |||
{ | |||
private readonly HttpClient _httpClient; | |||
public GitHubService(HttpClient client) | |||
{ | |||
_httpClient = client; | |||
_httpClient.BaseAddress = new Uri("https://api.github.com/"); | |||
_httpClient.DefaultRequestHeaders.Add("User-Agent", "GitHub-Service"); | |||
} | |||
public async Task<string> GetRepositoryInfo(string repo) | |||
{ | |||
return await _httpClient.GetStringAsync($"repos/{repo}"); | |||
} | |||
} | |||
// 気象API用サービス | |||
public class WeatherService | |||
{ | |||
private readonly HttpClient _httpClient; | |||
public WeatherService(HttpClient client) | |||
{ | |||
_httpClient = client; | |||
_httpClient.BaseAddress = new Uri("https://api.weather.com/"); | |||
_httpClient.DefaultRequestHeaders.Add("User-Agent", "Weather-Service"); | |||
} | |||
public async Task<string> GetWeatherInfo(string location) | |||
{ | |||
return await _httpClient.GetStringAsync($"weather/{location}"); | |||
} | |||
} | |||
// 複数APIを利用するサービスのインターフェース | |||
public interface IMultiApiService | |||
{ | |||
Task RunExample(); | |||
} | |||
// 複数のAPIを利用する実装 | |||
public class MultiApiService : IMultiApiService | |||
{ | |||
private readonly IHttpClientFactory _clientFactory; | |||
private readonly GitHubService _githubService; | |||
private readonly WeatherService _weatherService; | |||
private readonly MultiBaseUriService _multiBaseUriService; | |||
public MultiApiService(IHttpClientFactory clientFactory, GitHubService githubService, WeatherService weatherService, | |||
MultiBaseUriService multiBaseUriService) | |||
{ | |||
_clientFactory = clientFactory; | |||
_githubService = githubService; | |||
_weatherService = weatherService; | |||
_multiBaseUriService = multiBaseUriService; | |||
} | |||
public async Task RunExample() | |||
{ | |||
// 方法 1 : 名前付きHttpClientの使用 | |||
try | |||
{ | |||
var githubClient = _clientFactory.CreateClient("github"); | |||
var weatherClient = _clientFactory.CreateClient("weather"); | |||
var githubResponse = await githubClient.GetStringAsync("repos/dotnet/runtime"); | |||
var weatherResponse = await weatherClient.GetStringAsync("weather/tokyo"); | |||
Console.WriteLine("Named Clients Response:"); | |||
Console.WriteLine($"GitHub: {githubResponse.Substring(0, 100)}..."); | |||
Console.WriteLine($"Weather: {weatherResponse.Substring(0, 100)}..."); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine($"Named clients error: {ex.Message}"); | |||
} | |||
// 方法 2 : 型付きHttpClientの使用 | |||
try | |||
{ | |||
var githubInfo = await _githubService.GetRepositoryInfo("dotnet/runtime"); | |||
var weatherInfo = await _weatherService.GetWeatherInfo("tokyo"); | |||
Console.WriteLine("\nTyped Clients Response:"); | |||
Console.WriteLine($"GitHub: {githubInfo.Substring(0, 100)}..."); | |||
Console.WriteLine($"Weather: {weatherInfo.Substring(0, 100)}..."); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine($"Typed clients error: {ex.Message}"); | |||
} | |||
// 方法 3 : 動的なベースURI切り替え | |||
try | |||
{ | |||
var githubResponse = await _multiBaseUriService.SendRequest("github", "repos/dotnet/runtime"); | |||
var weatherResponse = await _multiBaseUriService.SendRequest("weather", "weather/tokyo"); | |||
Console.WriteLine("\nMulti Base URI Service Response:"); | |||
Console.WriteLine($"GitHub: {githubResponse.Substring(0, 100)}..."); | |||
Console.WriteLine($"Weather: {weatherResponse.Substring(0, 100)}..."); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine($"Multi base URI error: {ex.Message}"); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
| 206行目: | 583行目: | ||
return resBodyStr; | return resBodyStr; | ||
} | |||
// HTTPリクエストメッセージを生成する | |||
// httpMethod : HTTPメソッドのオブジェクト | |||
// requestEndPoint : 通信先のURL | |||
private HttpRequestMessage CreateRequest(HttpMethod httpMethod, string requestEndPoint) | |||
{ | |||
var request = new HttpRequestMessage(httpMethod, requestEndPoint); | |||
return this.AddHeaders(request); | |||
} | |||
// HTTPリクエストにヘッダーを追加する | |||
// request : リクエスト | |||
private HttpRequestMessage AddHeaders(HttpRequestMessage request) | |||
{ | |||
request.Headers.Add("Accept", "application/json"); | |||
request.Headers.Add("Accept-Charset", "utf-8"); | |||
// 例えば、認証通過後のトークンが "Authorization: Bearer {トークンの文字列}" のように必要な場合は追加する | |||
return request; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== POST ==== | |||
==== POST : テキストファイル ==== | |||
以下の例では、リクエストのボディにJSON形式の内容を格納して送受信している。<br> | |||
JSONは、JS、Ruby、Python、PHP等では連想配列を使用して簡単に作成できるが、C#においては<code>Dictionary</code>型を使用および変換後、<code>StringContent</code>型に情報を付加してリクエストに格納する。<br> | JSONは、JS、Ruby、Python、PHP等では連想配列を使用して簡単に作成できるが、C#においては<code>Dictionary</code>型を使用および変換後、<code>StringContent</code>型に情報を付加してリクエストに格納する。<br> | ||
<br> | <br> | ||
APIの認証方式において、事前に与えられているAPIキーや他の認証情報の文字列を送信する時、認証が成功した場合はアクセストークンを返却して、以降はそのアクセストークンをリクエストヘッダに追加してAPIを呼ぶことがある。<br> | |||
その場合は、以下の例と同様の処理となる。<br> | その場合は、以下の例と同様の処理となる。<br> | ||
<br> | <br> | ||
リクエストのボディにおいて、引数に指定の形式でAPIキー等を格納してPOSTで送信する時、レスポンスのボディの一部にトークンが格納されて返される。<br> | |||
以下の例では、内部メソッドであるAddHeaders() | 以下の例では、内部メソッドであるAddHeaders()において固定のヘッダの追加のみを行っているが、ここにトークンが格納される場合は追加する処理を記述することにより使い回すことができる。<br> | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
// | // リクエストのボディに文字列のキーをJSON形式で格納してPOSTを送受信する | ||
public string Post(string someKey) | public string Post(string someKey) | ||
{ | { | ||
| 282行目: | 682行目: | ||
return request; | return request; | ||
} | } | ||
</syntaxhighlight> | |||
<br> | |||
==== POST : バイナリファイル ==== | |||
POSTリクエストは、テキストファイルやPDFファイル等のバイナリファイルをアップロードすることができる。<br> | |||
バイナリファイルを送信するためには、MIMEタイプを<code>multipart/form-data</code>に指定する。<br> | |||
<br> | |||
以下の例では、マルチパートで区切ることにより、複数のデータを送信している。<br> | |||
マルチパートの1つ目は<code>StringContent</code>型でテキストデータ、マルチパートの2つ目は<code>StreamContent</code>型でバイナリファイルのデータである。<br> | |||
これら2つのデータをボディ部に設定して、POSTリクエストで送信している。<br> | |||
<syntaxhighlight lang="c#"> | |||
// テキストデータおよびバイナリデータをボディ部にセットして、POSTリクエストを送受信する。 | |||
// filePath : アップロードするバイナリファイルのパス | |||
public string PostPdfFile(string filePath) | |||
{ | |||
String requestEndPoint = this.baseUrl + "resume/upload"; | |||
var request = this.CreateRequest(HttpMethod.Post, requestEndPoint); | |||
// Accept: multipart/form-dataを指定 | |||
request.Headers.Remove("Accept"); | |||
request.Headers.Add("Accept", "multipart/form-data"); | |||
// 生成するボディ部 | |||
// Content-Type : multipart/form-data; boundary = "{MultipartFormDataContentクラスが自動で設定}" | |||
// Content-Length: {MultipartFormDataContentクラスが自動で設定} | |||
var content = new MultipartFormDataContent(); | |||
// ボディ部1に--boundaryで区切られたマルチパートのテキストデータを追加 | |||
// --boundary | |||
// Content-Type: text/plain; charset=utf-8 | |||
// Content-Disposition: form-data; name=SamplePart | |||
// | |||
// Sample | |||
var multiDocumentsContent = new StringContent("Sample"); | |||
content.Add(multiDocumentsContent, "SamplePart"); | |||
StreamContent streamContent = null; | |||
var resStatusCoode = HttpStatusCode.NotFound; | |||
Task<HttpResponseMessage> response; | |||
String resBodyStr; | |||
using (var fileStream = File.OpenRead(filePath)) | |||
{ | |||
streamContent = new StreamContent(fileStream); | |||
// {Content-Disposition: form-data; name=file; filename="{ファイル名}"] | |||
//streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") | |||
//{ | |||
// Name = "file", | |||
// FileName = Path.GetFileName(filePath) | |||
//}; | |||
// ファイル名がマルチバイト文字の場合は文字化けするため、ファイル名を手動でエンコードしてヘッダを別に作成する | |||
var finfo = new FileInfo(filePath); | |||
var headerStr = string.Format("form-data; name=\"file\"; filename=\"{0}\"", finfo.Name); | |||
var headerValueByteArray = Encoding.UTF8.GetBytes(headerStr); | |||
var encodedHeaderValue = new StringBuilder(); | |||
foreach (var b in headerValueByteArray) | |||
{ | |||
encodedHeaderValue.Append((char)b); | |||
} | |||
streamContent.Headers.ContentDisposition = null; // デフォルトで用意されているので一旦削除 | |||
streamContent.Headers.Add("Content-Disposition", encodedHeaderValue.ToString()); | |||
// バイナリファイル (PDFファイル) | |||
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); | |||
streamContent.Headers.Add("Content-Length", fileStream.Length.ToString()); | |||
content.Add(streamContent, "file"); | |||
// 生成するボディ部 | |||
// ボディ部2に--boundaryから--boundary--までで区切られたマルチパートのバイナリデータを追加 | |||
// --boundary | |||
// Content-Disposition: form-data; name="file"; filename="{エンコードされたファイル名}" | |||
// Content-Type: application/pdf | |||
// Content-Length: {上で計算された値} | |||
// | |||
// {バイナリファイルの実体} | |||
// --boundary-- | |||
// 2つの部分を加えたボディ部をPOSTリクエストとして送信する | |||
request.Content = content; | |||
try | |||
{ | |||
response = httpClient.SendAsync(request); | |||
resBodyStr = response.Result.Content.ReadAsStringAsync().Result; | |||
resStatusCoode = response.Result.StatusCode; | |||
} | |||
catch (HttpRequestException e) | |||
{ // 通信が失敗した場合 | |||
return null; | |||
} | |||
fileStream.Close(); | |||
} | |||
if (!resStatusCoode.Equals(HttpStatusCode.OK)) | |||
{ // レスポンスが200以外の場合 | |||
return null; | |||
} | |||
if (String.IsNullOrEmpty(resBodyStr)) | |||
{ // レスポンスのボディが空の場合 | |||
return null; | |||
} | |||
return resBodyStr; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== MIMEタイプ (コンテンツタイプ) ==== | |||
application/x-www-form-urlencodedおよびmultipart/form-dataは、HTTPのPOSTリクエストでデータを送信するための異なるMIMEタイプである。<br> | |||
<br> | |||
* application/x-www-form-urlencoded | |||
*: HTMLフォームデータをエンコードして送信するためのデフォルトのMIMEタイプである。 | |||
*: データはキーと値のペアになり、それらのペアは<u>key1=value1&key2=value2</u>のように<code>&</code>で区切られる。 | |||
*: <br> | |||
*: 特殊文字は、パーセントエンコーディング(%エンコーディング)される。 | |||
*: 例: スペースは%20にエンコーディングされる。 | |||
*: <br> | |||
*: 一般的に、簡単なフォームデータやクエリ文字列を送信する場合に使用する。 | |||
*: <br> | |||
* multipart/form-data | |||
*: バイナリデータや大きなファイルを含む複数のデータタイプをサポートするためのMIMEタイプである。 | |||
*: <br> | |||
*: データは複数の部分に分かれており、各部分にはヘッダがあり、ヘッダにはContent-Dispositionが含まれる。 | |||
*: このヘッダは、データがどのように処理されるべきかを示している。 | |||
*: <br> | |||
*: バイナリデータを直接送信するために使用され、一般的には、ファイルのアップロード等で使用される。 | |||
*: <br> | |||
*: <code>--boundary</code>、<code>--boundary--</code>は、各部分の開始と終了を示すために使用され、部分はそれぞれ独立して処理される。 | |||
*: どちらを選択するかは、データの種類と送信する内容に依存する。 | |||
*: 一般的には、HTMLフォームでテキストデータを送信する場合は<u>application/x-www-form-urlencoded</u>が使用され、ファイルのアップロード等でバイナリデータを送信する場合は<u>multipart/form-data</u>が使用される。 | |||
<syntaxhighlight lang="css"> | |||
/* 例: */ | |||
--boundary | |||
Content-Disposition: form-data; name="key1" | |||
value1 | |||
--boundary | |||
Content-Disposition: form-data; name="key2" | |||
value2 | |||
--boundary-- | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||