Не вдаваясь в подробность о том, почему JSONP считается небезопасной (я предполагаю, что вы знаете, что уже есть), то Finaglers нити вы ссылка упоминает JsonpFilter
, которые могут быть применены к HTTP-сервис, возвращающий JSON для «обновления» его до JSONP.
Вот небольшой пример того, как подключить этот фильтр к конечной точке Finch.
import com.twitter.finagle.Http
import com.twitter.finagle.http.filter.JsonpFilter
import io.finch._
import io.finch.circe._
val endpoint: Endpoint[Map[String, String]] = get("jsonp") {
Ok(Map("foo" -> "bar"))
}
val service = endpoint.toServiceAs[Application.Json]
Http.server.serve(":8080", JsonpFilter.andThen(service))
JsonpFilter
мертвый простой. Он проверяет возвращаемую полезную нагрузку HTTP и представляет собой строку JSON, она переносит ее вызовом функции, имя которой передается в параметре строки запроса callback
(и соответственно изменяет тип содержимого на application/javascript
). Используя httpie, это будет выглядеть так:
$ http :8081/jsonp
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 39
Content-Type: application/json
{
"foo": "bar"
}
$ http :8080/jsonp?callback=myfunction
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 56
Content-Type: application/javascript
/**/myfunction({"foo":"bar"});
Большое спасибо Влад. Это именно то, чего я хотел. Я искал, где определить обратный вызов, но пока не прочитал ваш ответ, не понял, что JsonpFilter автоматически добавляет его. Это глупая идея разместить каждый веб-сервисный вызов в браузере. Любые предложения о том, нужно ли мне действительно отталкивать назад, чтобы попросить клиентов называть наш API там бэкэнд для звонков X-домена? Мы не можем позволить себе проблему обратной совместимости, используя CORS. –
Хм, подождите, все еще есть проблема: –