Предполагая, что вы работаете над проектом, основанным на JavaScript для клиентской стороны, и который отправляет запросы ajax на сервер через остальные веб-службы, вы можете столкнуться с некоторыми проблемами, особенно если обе стороны находятся в отдельном домене.
Действительно, по соображениям безопасности запросы ajax из одного домена A в другой домен B не авторизованы.
К счастью, W3C представил так называемый CORS (Cross Origin Resource Sharing), который дает возможность серверу лучше контролировать запросы между доменами.
Для этого сервер должен добавить HTTP-заголовки в ответ, указывающие на стороне клиента, которые являются разрешенными источниками.
Более того, если вы используете настраиваемые заголовки, ваш браузер не сможет их прочитать из соображений безопасности, поэтому вы должны указать, какие заголовки следует отображать. Итак, если в вашем коде JavaScript вы не можете получить свое собственное значение заголовка http, вы должны прочитать, что будет дальше
Список заголовков:
Access-Control-Allow-Origin
1
|
Access-Control-Allow-Origin: <origin> | * |
Параметр origin указывает URI, который может обращаться к ресурсу. Браузер должен обеспечить это. Для запросов без учетных данных сервер может указать «*» в качестве подстановочного знака, что позволяет любому источнику получать доступ к ресурсу.
Access-Control-Expose-Headers
1
|
Access-Control-Expose-Headers: X-My-Header |
Этот заголовок позволяет заголовкам белого списка серверов получать доступ к браузерам. Это очень полезно, когда вы добавляете пользовательские заголовки, потому что, добавляя их в заголовок «Access-Control-Expose-Headers», вы можете быть уверены, что ваш браузер сможет их прочитать.
Access-Control-Max-Age
1
|
Access-Control-Max-Age: <delta-seconds> |
Этот заголовок указывает, как долго могут кэшироваться результаты предварительного запроса.
Access-Control-Allow-методы
1
|
Access-Control-Allow-Methods: <method>[, <method>]* |
Определяет метод или методы, разрешенные при доступе к ресурсу. Это используется в ответ на предварительный запрос. Условия предварительного запроса обсуждаются выше.
Access-Control-Allow-Headers
1
|
Access-Control-Allow-Headers: <field-name>[, <field-name>]* |
Используется в ответ на запрос предварительной проверки, чтобы указать, какие заголовки HTTP можно использовать при выполнении фактического запроса.
Теперь посмотрим, как добавить этот заголовок с помощью Spring.
Сначала нам нужно создать класс, реализующий интерфейс Filter:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package hello; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; public class CORSFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest request= (HttpServletRequest) req; response.setHeader( "Access-Control-Allow-Origin" , "*" ); response.setHeader( "Access-Control-Allow-Methods" , "POST, GET, OPTIONS, DELETE" ); response.setHeader( "Access-Control-Allow-Headers" , "x-requested-with" ); response.setHeader( "Access-Control-Expose-Headers" , "x-requested-with" ); chain.doFilter(req, res); } } |
Теперь нам просто нужно добавить наш фильтр в контекст сервлета:
1
2
3
4
5
6
7
|
@Configuration public class ServletConfigurer implements ServletContextInitializer { @Override public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException { servletContext.addFilter( "corsFilter" , new CORSFilter()); } } |
И это все, теперь вы можете делать кросс-доменные запросы и использовать собственные заголовки http!