关于跨域访问—cors的跨域方案

菜鸡的开头

js刚入门,准备使用js的XMLHttpRequest跟后台进行数据交互,没想到
请求代码

function get(random){
    var url='http://127.0.0.1:8088/loginstatus?random='+random;
    var xhr = new XMLHttpRequest();//第一步:新建对象
    xhr.open('GET',url , true);
    xhr.send();
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var res = xhr.responseText;//获取到json字符串,解析
            console.log('res');
        }
    };
}

没想到居然控制台报错了
在这里插入图片描述
百度一下看到这个是浏览器行为的跨域访问问题
因为跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。
难搞难搞

转折

解决跨域问题的方案

目前比较常用的跨域解决方案有3种:

  • Jsonp 最早的解决方案,利用script标签可以跨域的原理实现。 限制: 需要服务的支持 只能发起GET请求

  • nginx反向代理 思路是:利用nginx反向代理把跨域为不跨域,支持各种请求方式 缺点:需要在nginx进行额外配置,语义不清晰

  • CORS 规范化的跨域请求解决方案,安全可靠。
    优势:在服务端进行控制是否允许跨域,可自定义规则 支持各种请求方式
    缺点:会产生额外的请求

我们一般会采用cors的跨域方案

眼前一亮

Cross-Origin Resource Sharing(CORS)跨来源资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS。

没错,上面的文字是复制来的

总的来讲,就是如果你判断这个请求是你家网站请求过来的.
那么这个网站的请求就是合法的,你就可以设置某个相应头,
告诉浏览器,这个请求是合法的!

相应头

响应头属性注释
Access-Control-Allow-Origin* 或者指定的ip如果这个值为指定的ip,比如配置了c,那么只有c能拿到数据,其他主机全部报403异常
Access-Control-Allow-MethodsGET, POST, PUT, DELETE, OPTIONS这个指定了能够进行跨域请求的请求方式,
Access-Control-Allow-HeadersContent-Type

我的服务器用的是纯手写解析http协议和打包http协议加线程并发处理,也就说我的程序干了Tomcat的活,所以我只需要在相应头加上以下的东西

String HTTP_OK="HTTP/1.1 200 OK\r\n" +
                "Server:BeesServer\r\n"+
                "Access-Control-Allow-Origin:*\r\n"+
                "Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS\r\n"+
                "Access-Control-Allow-Headers:Content-Type\r\n"+
                "Content-Type:text/html;charset=UTF-8\r\n"+
                "\r\n";
out.write(HTTP_OK+request);
out.newLine();
out.flush();

有些同学使用了Tomcat的可以这样

在web.xml 中添加filter

<filter>
    <filter-name>cros</filter-name>
    <filter-class>cn.bees.test.filter.CORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>cros</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

新增CORSFilter 类

@Component
public class CORSFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type");
        response.addHeader("Access-Control-Max-Age", "1800");//30 min
        filterChain.doFilter(request, response);
    }
}

写在最后

本菜鸡顺利完成了跨域访问数据请求的实现
下课

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页