1 使用Node.js创建http服务
### 查看node版本
C:\Users\Admin\WebstormProjects\html>node -v
v12.18.3
### 运行js文件
node xxx.js
2 谷歌游览器设置允许跨域
--args --disable-web-security --user-data-dir=F:\chrome
3 ajax跨域演示
// 使用node运行当前js文件
// node http.js
const http = require('http');
http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
const weather = "北京 晴 18~32";
response.write(weather);
response.end();
}).listen(8080);
<!--
http.html
-->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
$.ajax({
url: "http://localhost:8080/", success: function (result) {
alert(result);
}
});
</script>
4 服务端将要发送的数据填充在一条js语句中
- 服务端:将要发送的数据填充在一条js语句中
- 客户端:<script src="服务端接口地址"
// node http.js
const http = require('http');
http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
const weather = "北京 晴 18~32";
//将要返回的实际数据,填充进一条合法的js语句中,进而返回一条js语句到客户端被script自动执行
response.write(`alert("${weather}")`);// alert("北京 晴 18~32")
response.end();
}).listen(8080);
<!--
http.html
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp-02</title>
</head>
<script src="http://localhost:8080/"></script>
<body>
</body>
</html>
// http.js
const http = require('http');
http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
const weather = "北京 晴 18~32";
response.write(`document.write("${weather}")`);// document.write("北京 晴 18~32")
response.end();
}).listen(8080);
<!--
http.html
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp-03</title>
</head>
<script src="http://localhost:8080/"></script>
<body>
</body>
</html>
5 服务端返回的是一个函数的调用
提前在客户端定义一个函数,用于处理服务端返回的请求,服务端仅使用函数名拼接一条函数调用的js语句
5.1 客户端script标签写死了
const http = require('http');
const url = require('url');
http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
const Url = url.parse(request.url, true);
console.log(Url);
//funName是我请求参数的key
const funName = Url.query.funName;
const weather = "北京 晴 18~32";
response.write(`${funName}("${weather}")`);// funName("北京 晴 18~32") 直接调用这个函数
response.end();
}).listen(8080);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp-04</title>
</head>
<script>
function show(weather) {
//怎么写由客户端决定
//document.write(weather);
//console.log(weather);
alert(weather);
}
//
//show("来自我自己的天气预报");
</script>
<!--!函数定义应该放在上面-->
<!--script是在页面写死了,只能在加载过程中执行一次-->
<script src="http://localhost:8080?funName=show">
</script>
<body>
</body>
</html>
5.2 动态创建script元素
每次单击按钮时动态创建 <script元素
const http = require('http');
const url = require('url');
http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
const Url = url.parse(request.url, true);
//console.log(Url);
//funName是我请求参数的key
const funName = Url.query.funName;
const weather = "北京 晴 18~32";
response.write(`${funName}("${weather}")`);// funName("北京 晴 18~32") 直接调用这个函数
response.end();
}).listen(8080);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp-03</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<button id="click">clickMe</button>
<script>
$("#click").click(function () {
// 不要用$("<script>")动态创建<script>元素
// 浏览器会强行将<script>解析为标签
const script = document.createElement("script");
script.src = 'http://localhost:8080?funName=show';
document.body.appendChild(script);
});
function show(weather) {
alert(weather);
//每次单击时都会创建<script>,反复单击会导致<script>堆积
//删除添加的script元素
$("body>script:last").remove();
}
</script>
<body>
</body>
</html>
6 jQuery 中的jsonp
jQuery对 jsonp方式跨域进行了终极的简化
// 服务端的代码还是一样都不能少
const http = require('http');
const url = require('url');
http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
const Url = url.parse(request.url, true);
// 只能是callback
const callBack = Url.query.callback;
const weather = "北京 晴 18~32";
response.write(`${callBack}("${weather}")`);// funName("北京 晴 18~32") 直接调用这个函数
setTimeout(function () {
response.end();
}, 1000);
}).listen(8080);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp-03</title>
</head>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<button id="click">天气预报</button>
<script>
$("#click").click(function () {
$.ajax({
url: "http://localhost:8080",
type: "get",
// 其实也是动态创建<script>
// 借助<script>发送跨域请求
// 必须有服务器端的支持!
// 打开游览器即可看到
dataType: "jsonp",
success: function (weather) {
alert(weather);
}
});
});
</script>
<body>
</body>
</html>
// SpringBoot项目
// http://localhost:5000/getAUth?callback=getAUth
@ResponseBody
@GetMapping("/getAUth")
public String getAUth(@RequestParam String callback) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
HashMap<String, String> auth = new HashMap<String, String>();
auth.put("1", "添加用户");
auth.put("2", "添加部门");
// ...
// 服务端需要特殊处理
return callback + "(" + mapper.writeValueAsString(auth) + ")";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp-05</title>
</head>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<button id="click">获取权限</button>
<script>
let auth;
$(document).ready(function () {
$("#click").click(function () {
$.ajax({
url: "http://localhost:5000/getAUth",
type: "get",
dataType: "jsonp",
success: function (data) {
auth = data;
console.log('auth => ', auth);
}
});
});
});
</script>
<body>
</body>
</html>
7 总结
jsonp 需要前后端配合