使用Spring框架为选项请求启用CORS


问题内容

每次我对服务进行PUT Ajax调用时,都会返回以下错误:

XMLHttpRequest无法加载http:// localhost:8080 / users /
edit
。对预检请求的响应未通过访问控制检查:请求的资源上不存在“ Access-
Control-Allow-Origin”标头。因此,不允许访问源’ http://
localhost:63342
‘。响应的HTTP状态码为403。

经过2天的调查,我已经尝试在我的代码上尝试下一个解决方案。

这是我加载必要类并运行应用程序的 主要类

@SpringBootApplication
@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer{

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(DispatcherServletInitializer.class, OptionsController.class,Application.class);
    }
}

DispatcherServilet初始化 ,在那里我启用dispatchOptionsRequest:

public abstract class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        registration.setInitParameter("dispatchOptionsRequest", "true");
        super.customizeRegistration(registration);
    }
}

一个 控制器, 用于处理所有选项要求:

@Controller
public class OptionsController {

    @RequestMapping(method = RequestMethod.OPTIONS)
    public HttpServletResponse handle(HttpServletResponse theHttpServletResponse) throws IOException {
        theHttpServletResponse.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
        theHttpServletResponse.addHeader("Access-Control-Max-Age", "60"); 
        theHttpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        theHttpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
        return theHttpServletResponse;
    }

}

我在做什么配置错误?


问题答案:

最后, DispatcheServlet 自定义初始化程序是真正解决我的问题的类。由于我实现了 optionsController
,因此OPTIONS请求失败,这是错误的。

所以我删除了 optionsController ,仅在我的Rest Controller中为OPTIONS请求添加了 handle
方法,就解决了问题:

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/users")
public class Users {

    @RequestMapping(
            value = "/edit",
            method = RequestMethod.PUT)
    public ResponseEntity<?> create(@RequestBody User user){
         ....
         ....
    }

    @RequestMapping(
            value = "/**",
            method = RequestMethod.OPTIONS
    )
    public ResponseEntity handle() {
        return new ResponseEntity(HttpStatus.OK);
    }
}