跨域问题及其解决方案

一、同源策略

同源策略是由 Netscape 提出的一个安全策略,它是浏览器最核心也是最基本的安全功能,如果缺少同源策略,则浏览器的正常功能可能都会受到影响,现在所有支持JavaScript的浏览器都会使用这个策略。
协议、域名、端口号只要有一个不相同,那么都是非同源

二、跨域问题

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

三、如何解决跨域问题

在这里插入图片描述

1. CORS

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

项目含义
Access-Control-Allow-Origin运行那些域名的访问,既访问来源
Access-Control-Allow-Credentials是否允许携带cookie
Access-Control-Allow-Headers允许哪些请求头,默认的除外
Access-Control-Allow-Methods允许请求的方法:OPTIONS,HEAD,GET,POST,PUT,DELETE等等

创建跨域拦截器实现HandlerInterceptor接口,并实现其方法,在请求处理前设置头信息,并放行
在这里插入图片描述
在springmvc的配置文件中配置拦截器,注意拦截的是所有的文件
在这里插入图片描述

2.JSONP 方式

$.ajax({
            type:"get",
            async:false,
            url:"http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName=Tom",
            dataType:"jsonp",//数据类型为jsonp
            jsonp:"backFunction",//服务端用于接收callBack调用的function名的参数
            success:function (data) {
                alert(data["passWord"]);
            },
            error:function () {
                alert("error");
            }

        });

我们修改了 dataType 的数据类型为 jsonp,并且新增了 jsop 属性值为 “backFunction”。

@WebServlet("/getPassWordByUserNameServlet")
public class UserServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userName = req.getParameter("userName");
        String passWord = null;
        if(userName != null){
            passWord = "123";
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("passWord",passWord);
        //1、第一种方法:*表示支持所有网站访问,也可以额外配置相应网站
        //resp.setHeader("Access-Control-Allow-Origin", "*");

        //2、第二种方法:jsonp
        String backFunction = req.getParameter("backFunction");
        resp.getWriter().println(backFunction+"("+jsonObject.toJSONString()+")");

        //resp.getWriter().println(jsonObject.toJSONString());
    }
}

1、在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,即一般的ajax是不能进行跨域请求的。但 img、iframe 、script等标签例外,这些标签可以通过src属性请求到其他服务器上的数据。利用 script标签的开放策略,我们可以实现跨域请求数据,当然这需要服务器端的配合。 Jquery中ajax 的核心是通过 XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加

2、当我们正常地请求一个JSON数据的时候,服务端返回的是一串 JSON类型的数据,而我们使用 JSONP模式来请求数据的时候服务端返回的是一段可执行的 JavaScript代码因为jsonp 跨域的原理就是用的动态加载 script的src ,所以我们只能把参数通过 url的方式传递,所以jsonp的 type类型只能是get

使用jQuery的jsonp插件

请求方式不只局限于get请求,还可以是post请求,但从服务器从获取的数据依然是jsonp格式

3.HttpClient 请求转发

这种方式相当于绕过浏览器的同源机制直接通过后端进行转发

package com.ys.servlet;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Create by YSOcean
 */
@WebServlet("/ToGetPassWordServlet")
public class ToGetPassWordServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取用户名
        String userName = req.getParameter("userName");
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //创建get请求
        HttpGet hget = new HttpGet("http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName="+userName);
        CloseableHttpResponse httpResponse = httpClient.execute(hget);
        int code = httpResponse.getStatusLine().getStatusCode();
        if(code == 200){
            String result = EntityUtils.toString(httpResponse.getEntity());
            resp.getWriter().print(result);
        }
        httpResponse.close();
        httpClient.close();

    }
}

4.nginx 转发

利用nginx反向代理,将请求分发到部署到相应项目的tomcat服务器,当然也不存在跨域问题。

#proxy服务器
server {
    listen       80;
    server_name  www.test.com;# 示例网站

	# 以下配置为开放测试环境,生成环境根据需求自行更改
		# 此处为设置全局跨域
        add_header Access-Control-Allow-Origin *;  #当前端只跨域不带cookie时,可为*,*通配符任意通常做开放测试
        add_header Access-Control-Allow-Credentials true; # 表示运行携带cookie
		add_header Access-Control-Allow-Methods: "OPTIONS, HEAD, GET, POST, PUT, DELETE";
		add_header Access-Control-Allow-Headers: "Origin, Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With";
    location / {
        proxy_pass   http://www.domain2.com:8080;  #反向代理
        proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
       
		# 如果在此处设置则为此路径下跨域设置
        
		 index  index.html index.htm;
    }
}

总结

CORS与JSONP的使用目的相同,但是比JSONP更强大。
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yemuxiaweiliang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值