AJAX--ajax的跨域问题及解决方案
跨域
跨域是指从一个域名的网页去请求另一个域名的资源
例如:从百度页面请求京东的资源
- 通过超链接是可以跨域访问
- 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反向代理