# Andere Server mit REQUEST aufrufen und Dateien mit DOWNLOAD speichern

> Nutze REQUEST() für HTTP-Aufrufe auf niedriger Ebene mit voller Kontrolle über Methode, Header, Query und Body und DOWNLOAD(), um eine entfernte Datei auf die Festplatte zu streamen.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: de
Content-SHA256: 6d168413fd583250d0363c429c3d2471fe77afe9ec9e3a916c37589fc3c53357
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

`REQUEST(options)` ist der HTTP-Client auf niedriger Ebene, auf dem `RESTBuilder` aufbaut. Übergib ein Objekt und verwende `await` (oder gib einen Callback als zweites Argument). Die nützlichen Optionen sind `url`, `method` (Standard `GET`), `query` (ein Objekt, das an die URL angehängt wird), `headers`, `cookies`, `body` (eine Zeichenkette oder ein Buffer), `type` (`json`, `text`, `html`, `xml`, `urlencoded` oder `raw`, was `content-type` setzt), `timeout` in Millisekunden und `noredirect`.

Das Ergebnis ist ein Objekt mit `status`, `headers`, `cookies` und `body` (eine Zeichenkette; parse JSON selbst mit `.parseJSON()`). Eine Antwort mit einem Fehlerstatus wie 404 ist **kein** Fehler: Prüfe `status`. Das Promise wird nur abgelehnt, wenn die Anfrage selbst fehlschlägt (Verbindung abgelehnt, Timeout, ungültiger Host).

`DOWNLOAD(url, filename)` streamt die Antwort in eine Datei und wird mit `{ status, size, filename }` aufgelöst. Es schaut nicht auf den Status, prüfe ihn also, bevor du die Datei verwendest.

```js controllers/request.js
exports.install = function() {
	ROUTE('GET /remote/', remote);
	ROUTE('POST /remote/ @json', remote_post);
	ROUTE('GET /remote/text/', remote_text);
	ROUTE('GET /call/', call);
	ROUTE('GET /download/', download);
};

function remote($) {
	$.json({ hello: 'world', name: $.query.name || null });
}

function remote_post($) {
	$.json({ received: $.body, token: $.headers['x-token'] || null });
}

function remote_text($) {
	$.plain('first line\nsecond line\n');
}

async function call($) {

	var get = await REQUEST({ url: $.hostname('/remote/'), query: { name: 'Louis' } });
	var post = await REQUEST({ method: 'POST', url: $.hostname('/remote/'), type: 'json', body: JSON.stringify({ a: 1 }), headers: { 'x-token': 'abc' } });
	var missing = await REQUEST({ url: $.hostname('/does-not-exist/') });

	var failed = null;
	try {
		await REQUEST({ url: 'http://127.0.0.1:1/' });
	} catch (e) {
		failed = true;
	}

	$.json({
		get: get.body.parseJSON(),
		post: post.body.parseJSON(),
		status: [get.status, missing.status],
		failed: failed
	});
}

async function download($) {
	var filename = PATH.tmp('forge-download.txt');
	var response = await DOWNLOAD($.hostname('/remote/text/'), filename);
	var content = require('fs').readFileSync(filename).toString('utf8');
	$.json({ status: response.status, size: response.size, content: content });
}
```
