AJAX跨域

发布于 2020-05-20  87 次阅读


因为自己搭建环境审计CMS的时候老是会遇到的这个问题:AJAX跨域。所以今天整理了一下解决ajax跨域的问题和方案。

通常使用cms上传文件或者图片的时候会出现接口错误的情况,比如:

检查控制台错误会发现

首先说一下什么是跨域?

跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签(可以直接跨域发送数据并接收数据)等 

ajax跨域,简单来说就是前端调用后端服务接口时,如果服务接口不是同一个域,就会产生跨域问题

如何解决跨域问题?

1、 在被请求的php文件中加入请求头部

header('Access-Control-Allow-Origin: *');

如果使用现成的框架或者直接用网上的CMS源码做项目,例如我今天审计PHPYUN时,如果不知道在哪个文件添加,就去看看其他文件开头,哪个文件被include最多,那多半就是了

2、jsonp 只支持get请求不支持post请求

用法:①dataType改为jsonp     ②jsonp : "jsonpCallback"————发送到后端实际为http://a.a.com/a/FromServlet?userName=644064&jsonpCallback=jQueryxxx     ③后端获取get请求中的jsonpCallback    ④构造回调结构

$.ajax({
			type : "GET",
			async : false,
			url : "http://a.a.com/a/FromServlet?userName=644064",
			dataType : "jsonp",//数据类型为jsonp  
			jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数
			success : function(data) {
				alert(data["userName"]);
			},
			error : function() {
				alert('fail');
			}
		});
//后端
        String jsonpCallback = request.getParameter("jsonpCallback");
		//构造回调函数格式jsonpCallback(数据)
		resp.getWriter().println(jsonpCallback+"("+jsonObject.toJSONString()+")");

3、httpClient内部转发

实现原理很简单,若想在B站点中通过Ajax访问A站点获取结果,固然有ajax跨域问题,但在B站点中访问B站点获取结果,不存在跨域问题,这种方式实际上是在B站点中ajax请求访问B站点的HttpClient,再通过HttpClient转发请求获取A站点的数据结果。但这种方式产生了两次请求,效率低,但内部请求,抓包工具无法分析,安全。

$.ajax({
			type : "GET",
			async : false,
			url : "http://b.b.com:8080/B/FromAjaxservlet?userName=644064",
			dataType : "json",
			success : function(data) {
				alert(data["userName"]);
			},
			error : function() {
				alert('fail');
			}
		});
@WebServlet("/FromAjaxservlet")
public class FromAjaxservlet extends HttpServlet{
	
	
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			//创建默认连接
			CloseableHttpClient httpClient = HttpClients.createDefault();
			//创建HttpGet对象,处理get请求,转发到A站点
			HttpGet httpGet = new HttpGet("http://a.a.com:8080/A/FromServlet?userName="+req.getParameter("userName")); 
                        //执行
			CloseableHttpResponse response = httpClient.execute(httpGet);
			int code = response.getStatusLine().getStatusCode();
			//获取状态
			System.out.println("http请求结果为:"+code);
			if(code == 200){
                                //获取A站点返回的结果
				String result = EntityUtils.toString(response.getEntity());
				System.out.println(result);
                                //把结果返回给B站点
				resp.getWriter().print(result);
			}
			response.close();
			httpClient.close();
		} catch (Exception e) {
		}
	}
}

在下有胡说的地方请联系我。后面两点我也没试过,只是做一个笔记,2、3点转自 CSDN


学不动了,带带孩子吧。