Подтвердить что ты не робот

Автоматически добавлять заголовок для каждого ответа

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

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

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

<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

4b9b3361

Ответ 1

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

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);
    }

}

Не забудьте добавить фильтр в контекст spring:

<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>

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

<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 (..))

Ответ 3

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

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

Ответ 4

В 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

Ответ 5

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

Ответ 6

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

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;
}