jsonp实现JavaScript跨域请求

时间:2022-11-21 21:39:44

跨域方法有很多种,今天就来看一下,jsonp是如何实现跨域请求的。


一. 什么是跨域,以及为什么要跨域

(1)所谓跨域请求,就是跨不同的域来发送请求,不同的域就是在协议、域名、端口号中,有一个不同,就是不同的域,比如:http://localhost:8080http://localhost:8888就是不同的域,因为端口号不同。
(2)如果我们在做一个比较大的项目,不同的资源部署在不同的服务器上,这时就需要跨域请求,然而为了保护信息的安全,浏览器并不支持跨域请求,这是浏览器默认的安全策略,即同源策略(同源指协议、域名、端口号完全相同)。因此一些跨域方法就应运而生。

二. jsonp跨域请求原理

我们平时在写HTML代码时,可以发现,<img>标签,<script>标签,以及CSS的<link>标签 ,里面的引用资源,都是可以跨域的,当代码运行到标签时就直接加载所引用的资源。jsonp就是利用<script> 标签的具有可跨域的特性来实现跨域请求的。

过程如下:

  • 首先创建<script> 标签,在src中声明要发送请求的路径,将要执行的函数以键值对的形式用问号链接附在路径的后面;
  • 然后服务器端响应请求,将数据以函数名加参数的形式返回;
  • 返回成功浏览器就直接执行要执行的js函数,删除刚才创建的<script> 标签。

三. 自己写的小例子
HTML代码:

<!DOCTYPE html>
<html>
<head>
<title>jsonp练习</title>
</head>
<body>
<button id="btn">点我</button>

<script>
//请求成功要执行的函数
function func(data){
console.log(data);
}

document.getElementById("btn").addEventListener("click", function(){
var scriptTag = document.createElement("script");
//链接后面表达式为要传递给服务器端的函数名,函数名为要执行的函数
scriptTag.src = "http://localhost:8080/user?callback=func";
document.getElementsByTagName("body")[0].appendChild(scriptTag);
document.getElementsByTagName("body")[0].removeChild(scriptTag);
}, true);

</script>
</body>
</html>

在代码中一旦点击按钮,就立即创建<script> 标签,然后给src属性附上请求路径,在将标签加到body中,请求就立即响应,一旦响应成功,就删除标签。

服务器端代码:


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

/**
* Created by jing on 2017/3/16.
*/

public class UserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String funcname = request.getParameter("callback"); //接收函数名参数
Writer out = response.getWriter();
//返回数据为函数名加参数,以字符串形式返回,即:func("nihao");
String data = funcname + "('"+ "nihao" + "')";
out.write(data);
System.out.println(data);

}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

成功后再浏览器控制台输出:
jsonp实现JavaScript跨域请求


这是一个很简单的小例子,只是返回了字符串,要返回json格式的在后台封装就好,还有一点要提醒下,jsonp只能是get请求,不能是post请求,看到很多帖子,把它和ajax做比较,个人觉得它和ajax是两个不同的东西,ajax是通过XMLHttpRequest对象来实现请求响应的,两者不是一个原理。这是关于jsonp的内容,请多指教。