Ajax非同源服务器请求数据 jsonp和CORS跨域资源共享


Ajax请求限制
Ajax只能向自己的服务器发送请求。比如现在有一个A网站、有一个B网站,A网站中的HTML文件只能向A网站服务器中发送Ajax请求,B网站中的HTML文件只能向B网站中发送Ajax请求,但是A网站是不能向B网站发送Ajax请求的,同理,B网站也不能向A网站发送Ajax请求

1.通过jsonp

  1. 将不同源的服务器端请求地址写在script标签的src属性中
  2. 服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数。
  3. 在客户端全局作用域下定义函数fn
  4. 在fn函数内部对服务器端返回的数据进行处理

这是服务器一下的html代码

<script>
		function fn (data) {
			console.log('客户端的fn函数被调用了')
			console.log(data);
		}
	</script>
	<!-- 1.将非同源服务器端的请求地址写在script标签的src属性中   localhost:3001是二号服务器的端口-->
	<script src="http://localhost:3001/test"></script>

这是服务器二的配置

app.get('/test', (req, res) => {
	const result = 'fn({name: "张三"})';
	res.send(result);
});

因为做工程时前端后端是分开的 所以你在html页面上的函数名后端并不知道,我们需要将函数名传到服务器 这样服务器就不用写函数名了

优化代码如下

<script>
		function fn2 (data) {
			console.log('客户端的fn函数被调用了')
			console.log(data);
		}
	</script>
	<script type="text/javascript">
		// 获取按钮
		var btn = document.getElementById('btn');
		// 为按钮添加点击事件
		btn.onclick = function () {
			// 创建script标签
			var script = document.createElement('script');
			// 设置src属性
			script.src = 'http://localhost:3001/better?callback=fn2';
			// 将script标签追加到页面中
			document.body.appendChild(script);
			// 为script标签添加onload事件
			script.onload = function () {
				// 将body中的script标签删除掉
				document.body.removeChild(script);
			}
		}
	</script>

服务器代码如下

app.get("/better", (req, res) => {
  // //接收客户端传递过来的函数的名称
  // const fnName = req.query.callback;
  // //将函数名称对应的函数调用代码返回给客户端
  // const data = JSON.stringify({name: "张三"});
  // const result = fnName + '('+ data +')';
  // setTimeout(() => {
  // 	res.send(result);
  // }, 1000)
  //这里jsonp实现的功能和上面注释的功能一样
  res.jsonp({ name: "lisi", age: 20 });
});

下面是我做的一个小案例 获取天气
html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>使用jsonp获取腾讯天气信息</title>
    <link
      rel="stylesheet"
      href="/assets/bootstrap/dist/css/bootstrap.min.css"
    />
    <style type="text/css">
      .container {
        padding-top: 60px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <table
        class="table table-striped table-hover"
        align="center"
        id="box"
      ></table>
    </div>
    <script src="/js/jsonp.js"></script>
    <script src="/js/template-web.js"></script>
    <script type="text/html" id="tpl">
      <tr>
        <th>时间</th>
        <th>温度</th>
        <th>天气</th>
        <th>风向</th>
        <th>风力</th>
      </tr>
      {{each info}}
      <tr>
        <td>{{dateFormat($value.update_time)}}</td>
        <td>{{$value.degree}}</td>
        <td>{{$value.weather}}</td>
        <td>{{$value.wind_direction}}</td>
        <td>{{$value.wind_power}}</td>
      </tr>
      {{/each}}
    </script>
    <script>
      // 获取table标签
      var box = document.getElementById("box");

      function dateFormat(date) {
        var year = date.substr(0, 4);
        var month = date.substr(4, 2);
        var day = date.substr(6, 2);
        var hour = date.substr(8, 2);
        var minute = date.substr(10, 2);
        var seconds = date.substr(12, 2);

        return (
          year +
          "年" +
          month +
          "月" +
          day +
          "日" +
          hour +
          "时" +
          minute +
          "分" +
          seconds +
          "秒"
        );
      }

      // 向模板中开放外部变量
      template.defaults.imports.dateFormat = dateFormat;

      // 向服务器端获取天气信息
      jsonp({
        url: "https://wis.qq.com/weather/common",
        data: {
          source: "pc",
          weather_type: "forecast_1h",
          // weather_type: 'forecast_1h|forecast_24h',
          province: "河南省",
          city: "平顶山市",
        },
        success: function (data) {
          var html = template("tpl", { info: data.data.forecast_1h });
          box.innerHTML = html;
        },
      });
    </script>
  </body>
</html>

服务器一只要开放下端口 就可以
在这里插入图片描述

2.CORS跨域资源共享

一般来说ajax不能非同域通信 但是如果你服务器加入Access-Control-Allow-Origin这个响应头 相当于一个服务器的白名单 如果你在 那么你就可以去访问这个服务器 这个只用配置服务器 html页面照常不变
以下为代码详解

// 拦截所有请求
app.use((req, res, next) => {
  // 1.允许哪些客户端访问我
  // * 代表允许所有的客户端访问我
  // 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
  res.header("Access-Control-Allow-Origin", "http://localhost:3000");
  // 2.允许客户端使用哪些请求方法访问我
  res.header("Access-Control-Allow-Methods", "get,post");
  // 允许客户端发送跨域请求时携带cookie信息
  res.header("Access-Control-Allow-Credentials", true);
  next();
});
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值