Настройка заголовков для формы AMP в Rails - PullRequest
2 голосов
/ 14 июня 2019

Моя форма AMP в Rails возвращает эту ошибку в терминале:

Completed 406 Not Acceptable in 338ms (ActiveRecord: 54.1ms)
ActionController::UnknownFormat (InscriptionsController#create is missing a template for this request format and variant.
request.formats: ["application/json"]
request.variant: []):

И в браузере:

POST http://localhost:3000/inscriptions?__amp_source_origin=http%3A%2F%2Flocalhost%3A3000 406 (Not Acceptable)
Response must contain the AMP-Access-Control-Allow-Source-Origin header
Form submission failed: Error: Response must contain the AMP-Access-Control-Allow-Source-Origin header​​​
at bb.f.assert (https://cdn.ampproject.org/v0.js:21:319)
at y (https://cdn.ampproject.org/v0.js:26:213)
at https://cdn.ampproject.org/v0.js:179:339

Однако я следовал примеру кода CORS, предоставленномуофициальная документация https://amp.dev/documentation/guides-and-tutorials/learn/amp-caches-and-cors/amp-cors-requests?referrer=ampproject.org, и согласно валидации AMP все нормально,

Это мой контроллер:

def create
  @inscription = Inscription.new(inscription_params)
  @inscription.save
  subscriber_email = inscription_params[:email].downcase
  if Subscriber.where(email: subscriber_email).count == 0
    @subscriber = Subscriber.new
    @subscriber.email = subscriber_email
    @subscriber.save
    @new_subscriber = true
  else
    @subscriber = Subscriber.where(email: subscriber_email).first
    @new_subscriber = false
  end
 [...]
 respond_to do |format|
  format.html { redirect_to root_path, notice: "Merci ! Nous avons bien reçu votre inscription !" }
  format.js
  format.json {
    allowed_origins = ["https://example.com", "https://example.com.cdn.ampproject.org/", "http://example.com.amp.cloudflare.com", "https://cdn.ampproject.org"]
    allowed_source_origin = "https://example.com"
    source_origin = params[:__amp_source_origin]
    origin = request.headers["Origin"]
    response.set_header('Content-type', 'application/json')
    response.set_header('Access-Control-Allow-Credentials', 'true')
    response.set_header('Access-Control-Allow-Origin', origin)
    response.set_header('AMP-Access-Control-Allow-Source-Origin', source_origin)
    p response.headers
  }
  end
end

Можете ли вы помочь мне с этим?Я, вероятно, сделал что-то не так с заголовками.Большое спасибо!

1 Ответ

3 голосов
/ 22 июня 2019

Я думаю, что главная проблема здесь не в неизвестном формате, а в шаблон

В показанной вами ошибке ясно, что вы отправляете правильный Content-Type в своем запросе

request.formats: ["application/json"]

И вы указали format.json в своем действии контроллера.

Так что единственное, что приходит на ум, - это проблема с ответом на ваш запрос. Теперь снова, глядя на сообщение об ошибке, там написано, что вам не хватает шаблона.

ActionController :: UnknownFormat (InscriptionController # создать отсутствует шаблон для этого формата и варианта запроса

Причина этого заключается в том, что вы не возвращаете json-ответ от действия контроллера

format.json {
    allowed_origins = ["https://example.com", "https://example.com.cdn.ampproject.org/", "http://example.com.amp.cloudflare.com", "https://cdn.ampproject.org"]
    allowed_source_origin = "https://example.com"
    source_origin = params[:__amp_source_origin]
    origin = request.headers["Origin"]
    response.set_header('Content-type', 'application/json')
    response.set_header('Access-Control-Allow-Credentials', 'true')
    response.set_header('Access-Control-Allow-Origin', origin)
    response.set_header('AMP-Access-Control-Allow-Source-Origin', source_origin)
    p response.headers
  }

Вам нужно либо визуализировать json непосредственно из действия контроллера, либо, если вы этого не сделаете,

Rails пытается найти подходящий шаблон для вашего контроллера действие.

и я думаю, что это главная причина этой ошибки.

Решение:

1. Добавьте оператор рендеринга к вашему действию контроллера

В этом случае вы можете сделать что-то вроде этого:

format.json {
    allowed_origins = ["https://example.com", "https://example.com.cdn.ampproject.org/", "http://example.com.amp.cloudflare.com", "https://cdn.ampproject.org"]
    allowed_source_origin = "https://example.com"
    source_origin = params[:__amp_source_origin]
    origin = request.headers["Origin"]
    response.set_header('Content-type', 'application/json')
    response.set_header('Access-Control-Allow-Credentials', 'true')
    response.set_header('Access-Control-Allow-Origin', origin)
    response.set_header('AMP-Access-Control-Allow-Source-Origin', source_origin)
    p response.headers

    render json: {}, status: :ok
  }

2. Создайте соответствующий файл вида, чтобы Rails мог его найти

Rails попытается найти файл представления с именем в качестве действия контроллера в имени каталога имени контроллера. Так что в вашем случае, поскольку имя контроллера InscriptionsController, поэтому ваш файл должен быть

Приложение / просмотров / надписи / create.json

Предложение

В указанной вами ссылке указано

Для запросов от разрешенных источников наш ответ будет содержать следующие заголовки:

Access-Control-Allow-Origin:

AMP-Access-Control-Allow-Source-Origin:

Заголовки Access-Control-Expose-: AMP-Access-Control-Allow-Source-Origin

Но вы не устанавливаете Access-Control-Expose-Headers в своем действии создания, которое должно быть установлено для того, чтобы клиент считывал дополнительные заголовки ответа в запросе CORS .

Надеюсь, это поможет.

...