如何实现 CORS 跨域资源共享

167 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

前言

前后端分离的项目中经常会遇到跨域问题,那么何为跨域请求了?

图片.png

从上述的图片我们可以得知,只要协议或者端口或者域名不同,则这样的请求为跨域请求。

解决方案

出现跨域问题,如何进行解决呢,我们可以通过一下几种方式来处理.

图片.png

JSONP 实现跨域

JSONP(JSON with Padding)是JSON的一种使用模式,可用于解决主流浏览器的跨域数据访问的问题。JSONP完成跨域请求需要服务端配合。

实现步骤

客户端发送JSONP请求

   $.ajax({
                async : false,
                url : "http://www.test.com/ajaxLogin"
                type : "post",
                dataType : 'jsonp',
                crossDomain : true,
                data : $("#loginForm").serialize(),
                success :loginCallback
          });
	
        //回调方法
	function loginCallback(res)
        {
            if (res.code == 0) {
                location.href =/home.html
            } else {
                 alert("登录失败");
            }
        }

服务端返回信息

    @RequestMapping("/ajaxLogin")
    public void ajaxLogin(HttpServletResponse response)
    {
        Result result = new Result
	result.setCode(200);
	result.setDesc("JSONP请求测试");    
        String json = JacksonUtil.serialize(result);
        WebUtil.writeJson("loginCallback(" + json + ")", response);
    }

JSON虽然可以实现跨域请求,但是此方法存在如下缺点:

  • 只支持部分标签,且仅支持GET请求。

  • 不安全可能存在XSS攻击的风险。

服务端支持CORS

采用Spring Boot服务端支持跨域请求,实现方式如下:

@Configuration
public class CorsConfig
{
    private CorsConfiguration buildConfig()
    {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        //1.允许传递cookie
        corsConfiguration.setAllowCredentials(true);
        // 2.允许任何域名使用
        corsConfiguration.addAllowedOrigin("*"); 
        // 3.允许任何头
        corsConfiguration.addAllowedHeader("*"); 
        // 4.允许任何方法(post、get,OPTIONS,PUT,DELETE等)
        corsConfiguration.addAllowedMethod("*"); 
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter()
    {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 5允许所有接口
        return new CorsFilter(source);
    }
}

Nginx 实现跨域

同源策略是浏览器需要遵守的标准,而如果是服务器向服务器请求则无需遵循同源策略了。所以通过反向代理服务器就可以有效地解决跨域问题了。

例如:服务器域名为:www.test1.com 而请求地址www.test.com/test 如何通过Nginx转发到统一域名请求。

在www.test.com域名服务器 配置Nginx转发请求即可。

location /test {
        proxy_pass http://www.test1.com/test;
    }

总结

本文通过几种方式实现了跨域请求,JSONP已经被技术的更新淘汰,后面两中方案需要根据不同的应用场景选择不同方案来解决。