• CORS和JSONP跨域


    Cross Origin Resource Share (CORS)

    CORS是一个跨域资源共享方案,为了解决跨域问题,通过增加一系列请求头和响应头,规范安全地进行跨站数据传输

    请求头主要包括

    请求头解释
    Origin Origin头在跨域请求或预先请求中,标明发起跨域请求的源域名。
    Access-Control-Request-Method Access-Control-Request-Method头用于表明跨域请求使用的实际HTTP方法
    Access-Control-Request-Headers Access-Control-Request-Headers用于在预先请求时,告知服务器要发起的跨域请求中会携带的请求头信息
    with-credentials 跨域请求携带cookie

    响应头主要包括

    响应头解释
    Access-Control-Allow-Origin Access-Control-Allow-Origin头中携带了服务器端验证后的允许的跨域请求域名,可以是一个具体的域名或是一个*(表示任意域名)。
    Access-Control-Expose-Headers Access-Control-Expose-Headers头用于允许返回给跨域请求的响应头列表,在列表中的响应头的内容,才可以被浏览器访问。
    Access-Control-Max-Age Access-Control-Max-Age用于告知浏览器可以将预先检查请求返回结果缓存的时间,在缓存有效期内,浏览器会使用缓存的预先检查结果判断是否发送跨域请求。
    Access-Control-Allow-Methods Access-Control-Allow-Methods用于告知浏览器可以在实际发送跨域请求时,可以支持的请求方法,可以是一个具体的方法列表或是一个*(表示任意方法)。

    如何使用

    • 客户端只需按规范设置请求头。
    • 服务端按规范识别并返回对应响应头,或者安装相应插件,修改相应框架配置文件等。具体视服务端所用的语言和框架而定。

    SpringBoot 设置CORS例子

    一个spring boot项目中关于CORS配置的一段代码

     
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            String temp = request.getHeader("Origin");
            httpServletResponse.setHeader("Access-Control-Allow-Origin", temp);
            // 允许的访问方法
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
    //         Access-Control-Max-Age 用于 CORS 相关配置的缓存
            httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
            httpServletResponse.setHeader("Access-Control-Allow-Headers",
                    "Origin, X-Requested-With, Content-Type, Accept,token");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");

    JSONP 跨域

    jsonp的原理就是借助HTML中的<script>标签可以跨域引入资源。所以动态创建一个<srcipt>标签,src为目的接口 + get数据包 + 处理数据的函数名。后台收到GET请求后解析并返回函数名(数据)给前端,前端<script>标签动态执行处理函数
    观察下面代码

    • 前端代码

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
      <script>
          var script = document.createElement('script');
          script.type = 'text/javascript';
      
          // 传参并指定回调执行函数为getData
          script.src = 'http://localhost:8080/users?username=xbc&callback=handleData';
          document.body.appendChild(script);
          // 回调执行函数
          function handleData(res) {
              data = JSON.stringify(res)
              console.log(data);
          }
      </script>
      </body>
      </html>
    • 后端代码(nodejs)

       
      var querystring = require('querystring');
      var http = require('http');
      var server = http.createServer();
      
      server.on('request', function(req, res) {
          var params = querystring.parse(req.url.split('?')[1]);
          var fn = params.callback;
      
          // jsonp返回设置
          res.writeHead(200, { 'Content-Type': 'text/javascript' });
          var data = {
              user: 'xbc',
              password: '123456'
          }
          res.write(fn + '(' + JSON.stringify(data) + ')');
      
          res.end();
      });
      
      server.listen('8080');
      console.log('Server is running at port 8080...');

    在该例子中,前台收到的res是这样的
    图片描述

    前端页面是这样的
    图片描述

    注意:JSONP既是利用了<srcipt>,那么就只能支持GET请求。其他请求无法实现

  • 相关阅读:
    [PHP] 适配器模式的日常使用
    [MySQL] timestamp和datetime的区别和大坑
    [PHP] foreach循环的引用赋值可能导致的问题
    [PHP] 邮件发送mail()函数失败问题 sendmail命令与postfix
    [日常] 腾讯云发送邮件失败问题
    [日常] 正则表达式 小括号() 中括号[] 大括号{}
    [Linux] awk与posix字符集
    [PHP] 工厂模式的日常使用
    [PHP] 抽象类abstract的回顾
    [日常]灵活的频率限制实现
  • 原文地址:https://www.cnblogs.com/jhflyfish/p/11708980.html
Copyright © 2020-2023  润新知