Access-Control-Allow-Origin和反向代理处理跨域

来源:互联网 发布:金山office for mac 编辑:程序博客网 时间:2024/06/07 15:59

什么是跨域

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。

所谓同源是指,域名,协议,端口相同。浏览器执行javascript脚本时,会检查这个脚本属于那个页面,如果不是同源页面,就不会被执行。

同源策略的目的,是防止黑客做一些做奸犯科的勾当。比如说,如果一个银行的一个应用允许用户上传网页,如果没有同源策略,黑客可以编写一个登陆表单提交到自己的服务器上,得到一个看上去相当高大上的页面。黑客把这个页面通过邮件等发给用户,用户误认为这是某银行的主网页进行登陆,就会泄露自己的用户数据。而因为浏览器的同源策略,黑客无法收到表单数据。

现在随着RESTFUL的流行,很多应用提供http/https接口的API,通过xml/json格式对外提供服务,实现开放架构。如,微博、微信、天气预报、openstack等网站和应用都提供restful接口。

Web应用也在向单页面方向发展。越来越多的web应用现在是这样的架构:

静态单个web页面

ajax调用

RESTFUL服务

我们本可以利用各个网站提供的API,做出很多精彩的Web应用。但浏览器执行javascript时的跨域限制,就成为了这类开放架构的拦路虎。

为了解决跨域请求的问题,我们需要在web应用中设置跨域的过滤器来实现,在web.xml总配置。在Springmvc框架中自定义过滤器filter,并能解决 Content-Type为application/json时跨域不通过的问题。

<filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.x.x.CorsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>corsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

同样的过滤代码

public class CorsFilter implements Filter {    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {        HttpServletResponse response = (HttpServletResponse) res;        response.setHeader("Access-Control-Allow-Origin", "*");        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, HEAD, DELETE, PUT");        response.setHeader("Access-Control-Max-Age", "3600");        response.setHeader("Access-Control-Allow-Headers",                "X-Requested-With, Content-Type, Authorization, Accept, Origin, User-Agent, Content-Range, Content-Disposition, Content-Description");        chain.doFilter(req, res);    }    public void init(FilterConfig filterConfig) {}    public void destroy() {}}

这样设置过滤器就可以很方便的绕过ajax请求jsonp的跨域请求。

参考: 

SpringMVC开启CORS支持

之前我们跨域是借助了浏览器对 Access-Control-Allow-Origin 的支持。但有些浏览器是不支持的,所以这并非是最佳方案

现在我们来利用nginx 通过反向代理 满足浏览器的同源策略实现跨域

首先,我先注释掉之前的跨域设置

然后我们回到nginx.conf 配置一个反向代理路径(新增红色部分)

server {        listen       8094;        server_name  localhost;        #charset koi8-r;        #access_log  logs/host.access.log  main;       location / {            root   html;            index  index.html index.htm;        }        location /apis {    rewrite  ^.+apis/?(.*)$ /$1 break;    include  uwsgi_params;       proxy_pass   http://localhost:1894;       }}

配置说明:配置一个/apis  重写到我们真正的api地址http://localhost:1894  形成一个代理的过程。

然后更改一下index1.html的api请求地址.

image

这样这个api的地址就跟当前页面index1.html处于同源位置了。就是我们配置的nginx监听地址 localhost:8094

然后我们再次在浏览器中访问 index1.html   可能请求到的知识缓存页面 请清除缓存或重启nginx

具体详见:

利用nginx 反向代理解决跨域问题



原创粉丝点击