JavaScript设计模式(十):牛郎织女-代理模式

本文涉及的产品
.cn 域名,1个 12个月
简介: 牛郎织女-代理模式

代理模式(Proxy)

由于一个对象不能直接引用另一个对象,所以需要通过代理对象在这两个对象之间起到中介的作用。

代理模式解决数据接口请求跨域问题

image.png

$.ajax({
   
   
    url: 'http://www.baidu.com/',
    success: function (res) {
   
   
        // 无法获取返回的数据
    }
});
  • 引发跨域问题的条件:
    1. 同一域名不同的端口号
      • 如: http://www.baidu.com:8001http://www.baidu.com:8002
    2. 同一域名不同协议
      • 如: http://www.baidu.comhttps://www.baidu.com
    3. 域名和域名对应的IP
      • 如: http://www.baidu.comhttp://61.135.169.125
    4. 主域与子域
      • 如: http://www.baidu.comhttp://b.a.com
    5. 子域与子域
      • 如: http://tieba.baidu.comhttp://fanyi.baidu.com

JSONP

当使用 script 标签的时候不会出现跨域问题,可以采用 script 进行解决

imgsrc 也有同样效果,但由于是单向的GET请求,所以在这里并不适用

  • 客户端:
      <body>
          <script>
              /**
               * 请求成功回调
              * @param {string} status   请求状态
              * @param {object} res      请求结果
              */
              function jsonpCallBack(status, res) {
          
          
                  console.log(status, res); // success {name: 'Lee', age: 18}
              }
          </script>
          <script src="http://127.0.0.1:8000?callback=jsonpCallBack&name=Lee"></script>
      </body>
    
  • 服务端:

      const http = require('http');
      const url = require('url');
    
      http.createServer(function (req, res) {
         
         
          let {
         
          query: q } = url.parse(req.url, true);
          let _callback = q['callback'];
          let data = {
         
          name: q['name'], age: 18 };
          res.end(`${_callback}('success', ${JSON.stringify(data)})`);
      }).listen(8000);
    
  • 特点:
    • 这种方式,你可以想象成河里面的一只小船,通过小船将你的请求发送给对岸,然后对岸的人们将数据放在小船里为你带回来

代理模板

利用表单传参,服务端重定向回调实现接收后端返回的数据

image.png

  • http://127.0.0.1:5500/域的文件

    • index.html

        <!DOCTYPE html>
        <html lang="en">
      
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>牛郎织女-代理模式-代理模板-A页面</title>
        </head>
      
        <body>
            <h1>A页面</h1>
      
            <iframe name="proxyIframe" id="proxyIframe" src=""></iframe>
      
            <form action="http://127.0.0.1:8000/" method="GET" target="proxyIframe">
                <label>回调函数名称:<input type="text" name="callback" value="callback"></label>
                <br />
                <label>重定向地址: <input type="text" name="proxy"
                        value="http://127.0.0.1:5500/demo.html"></label>
                <br />
                <input type="submit" value="提交">
            </form>
      
            <script>
                function callback(data) {
              
              
                    console.log('成功接收到后端返回的数据:', data);
                }
            </script>
        </body>
      
        </html>
      
    • demo.html

        <!DOCTYPE html>
        <html lang="en">
      
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>牛郎织女-代理模式-代理模板-B页面</title>
        </head>
      
        <body>
            <h1>B页面</h1>
            <script>
                // 获取地址栏传参
                function getUrlParam(url, paramname) {
              
              
                    var reg = new RegExp("(^|&)" + paramname + "=([^&]*)(&|$)");
                    // 查询匹配 substr(1)删除? match()匹配
                    var s = url.substr(1).match(reg);
                    if (s != null) {
              
              
                        return unescape(s[2]); // unescape() 函数可对通过 escape() 编码的字符串进行解码。
                    }
                    return null;
                }
      
                window.onload = function () {
              
              
                    let realURL = decodeURIComponent(location.search);
                    let _callback = getUrlParam(realURL, 'callback');
                    let _data = getUrlParam(realURL, 'data');
                    // 如果不在 index.html(A页面)中,那么不执行
                    if (top == self) return;
                    eval(`top.${_callback}(${_data})`); // 成功接收到后端返回的数据: {name: 'Lee', age: 18}
                };
            </script>
        </body>
      
        </html>
      
  • http://127.0.0.1:8000/域的文件(服务端)

      const http = require('http');
      const url = require('url');
    
      http.createServer(function (req, res) {
         
         
          // 接收参数
          let {
         
          query: {
         
          callback: _callback, proxy: _proxy } } = url.parse(req.url, true);
          // 传参
          let data = {
         
          name: 'Lee', age: 18 };
          // 重定向地址
          let redirectURL = `${_proxy}?callback=${_callback}&data=${
           
           JSON.stringify(data)}`;
          res.statusCode = 302;
          res.setHeader('Location', redirectURL);
          // 结束
          res.end();
      }).listen(8000);
    
目录
相关文章
|
1月前
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
30 3
|
2月前
|
设计模式 缓存 安全
设计模式——代理模式
静态代理、JDK动态代理、Cglib 代理
设计模式——代理模式
|
2月前
|
设计模式 Java 数据安全/隐私保护
Java设计模式-代理模式(7)
Java设计模式-代理模式(7)
|
3月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
50 1
|
3月前
|
设计模式 缓存 Java
【十一】设计模式~~~结构型模式~~~代理模式(Java)
文章详细介绍了代理模式(Proxy Pattern),这是一种对象结构型模式,用于给对象提供一个代理以控制对它的访问。文中阐述了代理模式的动机、定义、结构、优点、缺点和适用环境,并探讨了远程代理、虚拟代理、保护代理等不同代理形式。通过一个商务信息查询系统的实例,展示了如何使用代理模式来增加身份验证和日志记录功能,同时保持客户端代码的无差别对待。此外,还讨论了代理模式在分布式技术和Spring AOP中的应用,以及动态代理的概念。
【十一】设计模式~~~结构型模式~~~代理模式(Java)
|
3月前
|
设计模式 JavaScript 前端开发
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
|
3月前
|
设计模式
设计模式的基础问题之代理模式在工作中的问题如何解决
设计模式的基础问题之代理模式在工作中的问题如何解决
|
4月前
|
设计模式 算法 Go
iLogtail设计模式问题之代理模式在iLogtail中是如何应用的
iLogtail设计模式问题之代理模式在iLogtail中是如何应用的
|
4月前
|
设计模式 JavaScript 前端开发
JavaScript进阶 - JavaScript设计模式
【7月更文挑战第7天】在软件工程中,设计模式是解决常见问题的标准解决方案。JavaScript中的工厂模式用于对象创建,但过度使用可能导致抽象过度和缺乏灵活性。单例模式确保唯一实例,但应注意避免全局状态和过度使用。观察者模式实现了一对多依赖,需警惕性能影响和循环依赖。通过理解模式的优缺点,能提升代码质量。例如,工厂模式通过`createShape`函数动态创建对象;单例模式用闭包保证唯一实例;观察者模式让主题对象通知多个观察者。设计模式的恰当运用能增强代码可维护性。
81 0
|
4月前
|
设计模式 缓存 JavaScript
js设计模式实例
【7月更文挑战第2天】JavaScript设计模式包含工厂、单例、建造者、抽象工厂和代理模式等,它们是最佳实践和可重用模板,解决创建、职责分配和通信等问题。例如,工厂模式封装对象创建,单例确保全局唯一实例,建造者模式用于复杂对象构建,抽象工厂创建相关对象集合,而代理模式则控制对象访问。这些模式提升代码质量、可读性和灵活性,是高效开发的关键。
37 0

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    42
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    53
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    37
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    61
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    56
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    40
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    105
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    75