При обеспечении связи AJAX из вашего веб-приложения Angular рекомендуется кодировать интерфейс Typescript. Таким образом, вы можете установить поля, которые ожидаете получить от своего JSON, и настроить Observable для управления ими. В любом случае, что происходит внизу, на самом деле не совсем ясно и может привести вас к предположению, что Angular фактически отображает ключи и значения JSON в интерфейсе.
Но это не так.
Должен ли я использовать интерфейс вместо ‹любого›?
HttpClientModule дает вам возможность использовать поставщика HttpClient, который вы обычно вводите в свою службу для выполнения запросов AJAX. Внедрение выполняется с помощью внедрения зависимостей Angular, встроенного механизма, который помещает экземпляр службы в любой компонент, службу или класс Typescript, который должен его использовать.
Эта служба дает вам возможность вызывать get, post и другие методы для запуска HTTP-запроса любым методом. Каждый из этих методов службы должен передавать параметры по-разному, поскольку мы хотим поместить параметры в тело запроса HTTP (используя POST) или в заголовок HTTP (например, используя GET).
Самое интересное возникает, когда мы говорим о Observable, потому что все эти методы имеют Observable как возвращаемый тип.

В качестве встроенной реализации по умолчанию все эти методы обрабатывают <any> с помощью Observable, что означает, что каждый, кто подписывается на этот Observable (а затем запускает его), получит объект <any>.
Никогда не стоит работать с <any> объектами, если это не имеет внутреннего значения в вашем конкретном случае использования. Имейте в виду, что работа с универсальными объектами приводит к полностью неструктурированному объектному моделированию и может легко генерировать неправильные ссылки на поля и методы в вашем коде.
Поэтому вместо использования <any> мы используем интерфейсы Typescript для определения структуры JSON и отображения ее в нашем приложении.
Более того, мы можем создать экземпляр пользовательского класса, отличного от интерфейса, чтобы мы могли закодировать его, реализуя методы и полезные вещи, которые сделают наш экземпляр более мощным.
В некоторых приложениях это действие называется сериализацией (т.е. сериализовать JSON в модель). Я потратил много времени, пытаясь автоматически сериализовать JSON в класс экземпляра в Angular, но это невозможно сделать, если вы не реализуете фабричный шаблон проектирования или что-то в этом роде. Нет автоматизации, которая позволяет это. Даже если вы попытаетесь установить Observable, который обрабатывает JSON, на имя класса, когда вы проверяете объект с помощью отражения, вы получите общий объект. Вот почему большинство программистов используют фабричный шаблон или вспомогательный метод для создания экземпляра класса, а не притворяются, что Angular сделает это за вас.
В любом случае, читайте дальше, если хотите узнать больше о моделировании интерфейсов.
Скрытое и странное поведение
После того, как вы настроите интерфейс для обработки HttpClient Observable, вы получите что-то вроде этого:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AjaxResponse } from '../interfaces/ajax.interfaces';
@Injectable({
providedIn: 'root'
})
export class AjaxService {
endPoint = `/assets/mock.json`
constructor(
private http : HttpClient
) { }
getCandies() : Observable<MyInterface>{
return this.http.get<MyInterface>(`${this.endPoint}`)
}
}
Первое, что вы должны помнить, это то, что выражение типа, обрабатываемого Observable, на самом деле мало что делает.
Помните, что все, что передается через HTTP и XmlHttpRequest, является просто неструктурированным объектом, отражающим приложение типа MIME / JSON. Вот почему Observable обрабатывает <any>, а не общий TypeScript. Тот, кто столкнется с интерфейсом, сможет получить доступ к полям, предоставляемым интерфейсом, а не <any> полям. Но есть еще кое-что ...
Как было сказано ранее, указание интерфейса формализует наблюдаемые данные, но не удаляет и не отбрасывает любую избыточную информацию. Таким образом, даже если вы настроили интерфейс на три ключа JSON, вы все равно получите и сохраните в памяти JVM все, что вам отправит веб-сервер.
Это в основном вне вашего контроля, поскольку это внутреннее поведение JavaScript и AJAX: Javascript просто получает все и передает это в контекст приложения. Если вы когда-нибудь думали, что Angular удалит из памяти все, о чем вы не говорили, что хотите продолжать использовать поля интерфейса, вы увидите, что этого не произойдет.
Проверить это несложно: сделайте запрос AJAX, используйте интерфейс с некоторыми полями и используйте веб-службу в качестве конечной точки, которая отправит вам больше, чем ожидалось. Теперь попробуйте console.log интерфейс, и вы увидите, что он будет содержать все, что вы получили, как если бы вы вообще не использовали интерфейс.
Выводы и соображения безопасности
Помните об этом поведении Angular, потому что оно может выдать ваши гипотезы.
Иногда данные из AJAX остаются в памяти во время выполнения приложения в течение длительного времени - это зависит от того, как вы используете экземпляр интерфейса и когда его область действия заканчивается.
Когда вы работаете с удаленным API, не делайте вид, что получаете только то, что определяет ваш интерфейс, потому что вместо этого вы получите все.
Единственный способ избавиться от нежелательных данных - это использовать первый подход, о котором я упоминал. Если вы возьмете предстоящие данные (даже используя интерфейс) в своем компоненте Angular и создадите экземпляр своей пользовательской модели, интерфейс освободит память, как только область действия интерфейса закончится.
Помните, что JSON может содержать вредоносный код внутри функций, запускаемых ниже, в то время как вы даже не должны иметь их в своей памяти.