У меня работает два угловых 4 приложения , обслуживаемых через два различных приложения django (в качестве статических файлов. Это работает отлично). У меня есть «родительское приложение» и «дочернее приложение» .
Оба приложения обслуживаются через их собственное приложение Django в их собственных идентичных приложениях (мы буквально скопировали приложение django для обслуживания как родителя, так и ребенка). ]
ПРОБЛЕМА: Мы сталкиваемся с проблемой CORS между загрузкой дочернего приложения в родительское приложение в iFrame.
что происходит:
Приложение chld загружено родительским приложением
Родительское приложение:
<div *ngIf="theRoute">
<iframe [src]="myUrl" appHeght id="myIFrame"></iframe>
</div>
Мой родительский компонент приложения IFrame:
ngOnInit() {
// The Router is correct, and so are the params.
this.myRouter = this.route.params.subscribe(
params => {
...
this.myUrl = this.sanitizer.bypassSecurityTrustResourceUrl('http://127.0.0.1:8201/'); // location of the child
... // more stuff, including change detection
}
);
}
my Приложение PARENT DJANGO - SETTINGS.PY:
import os
import datetime
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = 'my parent secret'
DEBUG = True
ALLOWED_HOSTS = '*'
INSTALLED_APPS = [
'rest_framework',
'corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'spa.middleware.SPAMiddleware',
]
ROOT_URLCONF = 'my_project_proj.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'my_project_proj.wsgi.application'
# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'America/Chicago' #'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = './frontend/dist/parent-app'
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'http://localhost:8000',
'http://127.0.0.1:8000',
'http://127.0.0.1:8201',
'http://localhost:8201'
)
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
X_FRAME_OPTIONS = 'ALLOW'
Я также разрешил X_FRAME-OPTIONS = 'ALLOW-FROM http://localhost:8201 -> это местоположение родительского компонента. Я позволил оба localhost: 8200 и 127.0.0.1/8201. Оба дали одну и ту же ошибку.
И ЭТО МОЙ РЕБЕНОК Настройки приложения DJANGO:
import os
import datetime
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = 'my child secret'
DEBUG = True
ALLOWED_HOSTS = '*'
INSTALLED_APPS = [
'rest_framework',
'corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'spa.middleware.SPAMiddleware',
]
ROOT_URLCONF = 'my_child.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'my_child.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'America/Chicago' #'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = './frontend/dist/child-one-app'
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'http://localhost:8000',
'http://127.0.0.1:8000',
'http://127.0.0.1:8201',
'http://localhost:8201'
)
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
X_FRAME_OPTIONS = 'ALLOW'
Как видите, мой дочерний и родительский компоненты разрешают CORS. Но по какой-то причине я все еще получаю эту ошибку в своем IFrame:
При загрузке обнаружен неверный заголовок X-Frame-Options
'http://127.0.0.1:8201/':' РАЗРЕШИТЬ 'не является признанной директивой.
заголовок будет игнорироваться.
** И эта ошибка: **
ОШИБКА DOMException: заблокирован кадр с источником
"http://127.0.0.1:8000" от доступа к фрейму перекрестного происхождения.
Мой общий вопрос: , поэтому, несмотря на то, что я включил CORS как в приложении для родителей, так и в дочернем приложении, почему мое дочернее приложение все еще вызывает проблему с CORS ?. Я перепробовал все, чтобы получить доступ к этому перекрестному источнику, включая выполнение `iframeID.contentWindow.postMessage () и в моем дочернем приложении создать window.addEventListener ('message', myRecever, false). приложение-получатель в моем дочернем приложении ничего не делало, кроме называй себя снова и снова !!
Метод получения моего дочернего компонента:
import { Component, OnInit } from '@angular/core';
import { LoaderService } from './services/loader.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
private loaderService: LoaderService = LoaderService.getInstance();
constructor() {
window.addEventListener('message', this.receiveMessage, false);
}
ngOnInit() {
this.loaderService.removeSpinner();
}
private receiveMessage(event) {
console.log("event origin:" , event.origin);
event.source.postMessage('verified', event.origin);
}
}
Это событие console.log продолжает вызывать себя в моем iFrame и моем дочернем компоненте снова и снова! Зачем?!