2013-04-24 5 views
37

Я хочу добавить этот заголовок «Access-Control-Allow-Origin», «*» в каждый ответ, сделанный клиенту всякий раз, когда запрос сделал для контроллеров отдыха в моем приложении, чтобы разрешить перекрестное происхождение совместное использование ресурсов В настоящее время я вручную добавляю этот заголовок для каждого метода, подобного этомуавтоматически добавлять заголовок для каждого ответа

HttpHeaders headers = new HttpHeaders(); 
headers.add("Access-Control-Allow-Origin", "*"); 

Его работа, но очень расстраивает. Я нашел webContentInterceptor весной документы, которые позволяют нам изменять заголовки каждого ответа

<mvc:interceptors> 
<bean id="webContentInterceptor" 
class="org.springframework.web.servlet.mvc.WebContentInterceptor"> 
<property name="Access-Control-Allow-Origin" value="*"/> 
</bean> 
</mvc:interceptors> 

но когда я использую это он бросает ошибку, что свойство не найдено в имени Access-Control-Allow-Origin так есть ли другой способ, которым мы может автоматически добавлять заголовок для каждого ответа

Обновление! Spring Framework 4.2 значительно упрощает это путем добавления @CrossOrigin аннотации либо методу или самого контроллер https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

ответ

53

Я недавно попал в эту проблему и нашел это решение. Вы можете использовать фильтр, чтобы добавить эти заголовки:

import java.io.IOException; 

import javax.servlet.FilterChain; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.springframework.web.filter.OncePerRequestFilter; 

public class CorsFilter extends OncePerRequestFilter { 

    @Override 
    protected void doFilterInternal(HttpServletRequest request, 
            HttpServletResponse response, FilterChain filterChain) 
      throws ServletException, IOException { 
      response.addHeader("Access-Control-Allow-Origin", "*"); 
      if (request.getHeader("Access-Control-Request-Method") != null 
        && "OPTIONS".equals(request.getMethod())) { 
       // CORS "pre-flight" request 
       response.addHeader("Access-Control-Allow-Methods", 
         "GET, POST, PUT, DELETE"); 
       response.addHeader("Access-Control-Allow-Headers", 
         "X-Requested-With,Origin,Content-Type, Accept"); 
      } 
      filterChain.doFilter(request, response); 
    } 

} 

Не забудьте добавить фильтр к вашему яровой контексте:

<bean id="corsFilter" class="my.package.CorsFilter" /> 

и отображение в web.xml:

<filter> 
    <filter-name>corsFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>corsFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

Чтобы перейти немного дальше, вы можете указать профиль пружины, чтобы включить или отключить этот фильтр с чем-то вроде этого:

<beans profile="!cors"> 
    <bean id="corsFilter" class="my.package.FilterChainDoFilter" /> 
</beans> 

<beans profile="cors"> 
    <bean id="corsFilter" class="my.package.CorsFilter" /> 
</beans> 

(при условии, FilterChainDoFilter похож на CorsFilter но только делает filterChain.doFilter(request, response); в doFilterInternal (..))

+0

Мой фильтр не называется :(Я использую Spring Security, которая использует фильтры таким образом, у меня уже есть DelegatingFilterProxy, настроенный в web.xml. Любые предложения? – bentzy

+0

@Benny DelegatingFilterProxy - это просто прокси-сервер, который обертывает ваш фильтр так, как я вижу, он не может быть «уже зарегистрирован», потому что у вас может быть столько, сколько вы хотите. Попробуйте добавить еще один с правильным именем (в моем примере corsFilter). – Dayde

+0

Почему вы используете DelegatingFilterProxy в web.xml? Это не работает для меня. Он работает, только если я установил CorsFilter – Igorock

0

WebContentInterceptor не имеет свойства с именем Access-Control-Allow-Origin, и, насколько я могу судить, он не раскрывает какие-либо методов для установки заголовки ответов. Он устанавливает только некоторые заголовки, связанные с кешем, путем включения/отключения некоторых свойств. Но тривиально писать собственный перехватчик (или фильтр сервлетов), который делает это.

5

Если вы хотите установить заголовки для контроллера можно использовать @ModelAttribute аннотацию.

@ModelAttribute 
public void setVaryResponseHeader(HttpServletResponse response) { 
    response.setHeader("Vary", "Accept"); 
}  
0

Я также сталкиваюсь с этой проблемой, и я добавил, что этот код исправлен.

public static HttpServletResponse getResponse(HttpServletResponse response) { 
    response.setHeader("Access-Control-Allow-Origin", "*"); 
    response.setCharacterEncoding("UTF-8"); 
    response.setHeader("Access-Control-Allow-Methods", "POST, GET"); 
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); 
    return response; 
} 
1

В Spring 4, Вы можете использовать @CrossOrigin() , который позволяет вам перекрестный вопрос происхождения.

Из соображений безопасности браузеры запрещают вызов AJAX ресурсам, находящимся за пределами текущего источника. Например, когда вы проверяете свой банковский счет на одной вкладке, вы можете иметь сайт evil.com на другой вкладке. Сценарии от evil.com не должны делать запросы AJAX в ваш банковский API (снимая деньги с вашей учетной записи!), Используя ваши учетные данные.

Совместное использование ресурсов (CORS) - это спецификация W3C, реализованная большинством браузеров, которая позволяет вам гибко указать, какие запросы на междоменные запросы разрешены, вместо использования менее защищенных и менее мощных хаков, таких как IFrame или JSONP.

Spring Framework 4.2 GA предоставляет первоклассную поддержку для CORS из коробки, предоставляя вам более простой и эффективный способ настройки, чем стандартные решения на основе фильтров.

Вы можете добавить аннотацию @CrossOrigin к вашему методу аннотированного обработчика @RequestMapping, чтобы включить CORS на нем. По умолчанию @CrossOrigin позволяет все источники и методы HTTP, указанные в @RequestMapping аннотацию:

@RestController 
@RequestMapping("/account") 
public class AccountController { 

    @CrossOrigin 
    @RequestMapping("/{id}") 
    public Account retrieve(@PathVariable Long id) { 
     // ... 
    } 

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") 
    public void remove(@PathVariable Long id) { 
     // ... 
    } 
} 

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html

https://spring.io/guides/gs/rest-service-cors/

https://spring.io/blog/2015/06/08/cors-support-in-spring-framework