AJAX--ajax的跨域问题及解决方案

发布时间 2023-08-01 20:41:07作者: 洛小依ovo

跨域

跨域是指从一个域名的网页去请求另一个域名的资源
例如:从百度页面请求京东的资源
  • 通过超链接是可以跨域访问
  • form表单发送请求可以跨域访问
  • window.location.href document.location.href可以跨域访问
  • 使用script标签加载js文件,可以跨域
  • 加载其他站点的图片也可以跨域

 

ajax是否可以跨域

默认情况下,发送ajax跨域请求会出现一下错误
出现错误原因:跨域的时候不允许共享同一个XMLHttpRequest对象,因为共享同一个对象是不安全的
CORS策略阻止(同源策略阻止,
同源策略是浏览器的一种安全策略:协议一致,域名一致,端口号一致才是同源,
只要任意一个不一致,就是不同源
同源:XMLHttpRequest可以共享
不同源:XMLHttpRequest不可以共享

 

ajax跨域请求问题解决:

1、设置响应头

允许ajax跨域请求
在后端代码中设置
response.setHeader("Access-Control-Allow-Origin","*");
// 第二个参数为允许ajax跨域请求的url,*为所有都可以访问

2、jsonp原理

jsonp:json with padding(带填充的json)

jsonp不是一个完整的ajax的请求,只不过可以完成ajax的局部刷新的效果,是一个类ajax请求的机制

第一步:

  • 前端代码
<script src = "http://localhost:8081/b/jsonp1">
</script>
<script>
    function sayHello(data){
        alert(hello + data.name)
    }
</script>
  • 后端代码
// 在后端向前端响应一段js代码,相当于在script标签中写一段js
// out.print("sayHello()");
// out.print("alert(123)");
// 响应一段js代码,然后传一个json字符串给前端
out.print("sayHello({\"name\":\"zhangsan\"})");

第二步:

动态获取函数名,从前端获取函数名
<script src = "http://localhost:8081/b/jsonp1?fun=sayHello"></script>
String fun = request.getParameter("fun");
out.print(fun + "({\"name\":\"zhangsan\"})");
注意:jsonp解决跨域时只支持GET请求,不支持POST请求
第三步:
但是目前是没有达到局部刷新的效果
接下来解决页面局部刷新
 
点击某一个按钮之后执行scprit标签请求
<scprit>
    function sayHello(data){
        document.getElementById("mydiv").innerHTML = data.username
    }
    window.onload = () => {
        document.getElementById("btn").onclick = () => {
            // 加载scprit元素
            // 创建scprit元素
            const htmlScriptElement = document.createElement("scprit")
            // 设置script的type属性、src属性
            htmlScriptElement.type = "text/javascript"
            htmlScriptElement.src = "http://localhost:8081/b/jsonp1?fun=sayHello"
            // 将scprit元素添加到body中
            document.getElementsByTagName("body")[0].appendChild(htmlScriptElement)
        }
    }
</scprit>
<button id="btn"></button>
<div id="mydiv"></div>
// 后端响应一段json代码
out.print();

 

3、jQuery封装的jsonp

// 先引入jQuery文件
<script>
    $(function(){
        $("#btn").click(function(){
            $.ajax({
                type:"GET",
                // 虽然url这样写,但是他后面会自动加一个参数
                // http://localhost:8081/b/jsonp3?callback=jQuery943574
                // callback就是fun
                // jQuery943574就是函数名
                // 这个函数没有定义 jQuery自动生成,并且默认情况下会调用success函数
                url:"http://localhost:8081/b/jsonp3",
                dataType:"jsonp",// 指定的数据类型为jsonp
                jsonp:"fun",// 用来指定参数名字
                jsonCallback:,// 不用jQuery默认生成的为回调函数,自己指定,并且这个函数会调用sucdess函数
                success:function(data){// data就是接收一个json的格式
                    $("#div").html(data.username)
                }
            })
        })
    })
</script>
<button id="btn">jsonp</button>
<div id="mydiv"></div>
// 获取函数名
String callback = request.getParameter("callback")
response.getWriter().print(callback+"(json数据)")

 

4、代理机制httpclient

通过中间的java程序代理Servlet跨域请求
也就是java程序怎么进行跨域请求
  • 使用java程序怎么发送get/post请求
    第一种:使用jdk内置的API(java.net.URL),这些api是可以发送http请求(比较麻烦,直接使用封装好的
    第二种:使用第三方的开源组件,例如:apache的httpclient组件
  • 在java程序中,使用httpclient组件的代码
    可以在网上搜索使用

5、nginx反向代理