ABAP:ABAP解析xml文件的方法

news2024/11/13 11:16:21

目前我在ECC的系统找到两种实现XML解析的办法,第一种是通过strans创建转化例程,然后在程序中调用转化例程来转化xml,第二种是调用方法按照node解析xml。

要转化的xml文件demo如下

<?xml version="1.0" encoding="Windows-1252"?>
<PPSExport Version="1.1">
    <ProductionOperationFeedback>
        <Operation OrderNo="600001099">
            <OperationNo>0010</OperationNo>
            <PartNo>210402000001</PartNo>
            <WorkPlace>TruLaserCenter7030-1</WorkPlace>
            <CostCenter />
            <TimeStamp>21.06.2023 09:10:21</TimeStamp>
            <ReturnType>30</ReturnType>
            <ProcessedParts>3</ProcessedParts>
            <ScrapParts>0</ScrapParts>
            <MissingParts>0</MissingParts>
            <TargetProcessingTimePerPiece>0.35</TargetProcessingTimePerPiece>
            <ProcessingTime>3.4500</ProcessingTime>
            <SetupTime>0.0000</SetupTime>
            <MeasuringTime>0.0000</MeasuringTime>
            <OperationStart>21.06.2023 09:09:45</OperationStart>
            <OperationEnd>21.06.2023 09:10:21</OperationEnd>
            <PartWeight>3.93622</PartWeight>
            <PartArea>0.41892516</PartArea>
            <PartLength>1210.00000</PartLength>
            <PartWidth>490.60000</PartWidth>
            <Assembly>100260031100</Assembly>
            <DataExt />
            <OrderNoExt />
            <CollectiveOrder>10000176</CollectiveOrder>
            <ErpID />
            <QuantityReports>
                <QuantityReport>
                    <ReportingTime>21.06.2023 09:10:21</ReportingTime>
                    <ProcessedParts>3</ProcessedParts>
                    <ScrapParts>0</ScrapParts>
                    <MissingParts>0</MissingParts>
                    <BatchNo>123456</BatchNo>
                    <WorkPlace>TruLaserCenter7030-1</WorkPlace>
                    <ReportedBy>0101????</ReportedBy>
                    <Terminal>LAP361347</Terminal>
                </QuantityReport>
            </QuantityReports>
            <Consumption>
                <ResourceConsumption ResourceName="300102010012" ResourceType="20">
                    <ResourceDescription>300102010012</ResourceDescription>
                    <ResourceNote>DC01-012 3000x1250</ResourceNote>
                    <ResourceCategory />
                    <Consumption>3.75000</Consumption>
                    <UnitOfConsumption>m2</UnitOfConsumption>
                    <Rawmaterial>300102010012</Rawmaterial>
                    <Dimensions>
                        <Length>3000.00000</Length>
                        <Width>1250.00000</Width>
                        <Thickness>1.20000</Thickness>
                        <Unit>mm</Unit>
                    </Dimensions>
                </ResourceConsumption>
            </Consumption>
        </Operation>
    </ProductionOperationFeedback>
</PPSExport>

转化的结构定义如下

types: begin of ty_report,
  reportingtime type string,
  processedparts type string,
  scrapparts type string,
  missingparts type string,
  batchno type string,
  workplace type string,
  reportedby type string,
  terminal type string,
  end of ty_report.

types: begin of ty_reports,
  quantityreport type ty_report,
  end of ty_reports.

types: begin of ty_dimensions,
  length type string,
  width type string,
  thickness type string,
  unit type string,
  end of   ty_dimensions.

types: begin of ty_resourceconsumption,
*    resourcename TYPE string,
*    resourcetype TYPE string,
  resourcedescription type string,
  resourcenote type string,
  resourcecategory type string,
  consumption type string,
  unitofconsumption type string,
  rawmaterial type string,
  dimensions type ty_dimensions,
  end of ty_resourceconsumption.


data: lt_resourceconsumption type table of ty_resourceconsumption,
      ls_resourceconsumption type ty_resourceconsumption.

types: begin of ty_resourceconsumptions,
resourceconsumption like lt_resourceconsumption,
  end of ty_resourceconsumptions.

types: begin of ty_order,
  orderno type string,
  operationno type string,
  partno type string,
  workplace type string,
  costcenter type string,
  timestamp type string,
  returntype type string,
  processedparts type string,
  scrapparts type string,
  missingparts type string,
  targetprocessingtimeperpiece type string,
  processingtime type string,
  setuptime type string,
  measuringtime type string,
  operationstart type string,
  operationend type string,
  partweight type string,
  partarea type string,
  partlength type string,
  partwidth type string,
  assembly type string,
  dataext type string,
  ordernoext type string,
  collectiveorder type string,
  erpid type string,

  quantityreports type ty_reports,


  consumption type ty_resourceconsumptions,
end of ty_order.

方法一:STRANS

在事务码STRANS中创建转化例程:

 strans代码如下:

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">

  <tt:root name="ROOT"/>

  <tt:template>
    <PPSExport Version="1.1">
      <ProductionOperationFeedback>
        <Operation>
          <OrderNo>
            <tt:value ref="ROOT.ORDERNO"/>
          </OrderNo>
          <OperationNo>
            <tt:value ref="ROOT.OPERATIONNO"/>
          </OperationNo>
          <PartNo>
            <tt:value ref="ROOT.PARTNO"/>
          </PartNo>
          <WorkPlace>
            <tt:value ref="ROOT.WORKPLACE"/>
          </WorkPlace>
          <CostCenter>
            <tt:value ref="ROOT.COSTCENTER"/>
          </CostCenter>
          <TimeStamp>
            <tt:value ref="ROOT.TIMESTAMP"/>
          </TimeStamp>
          <ReturnType>
            <tt:value ref="ROOT.RETURNTYPE"/>
          </ReturnType>
          <ProcessedParts>
            <tt:value ref="ROOT.PROCESSEDPARTS"/>
          </ProcessedParts>
          <ScrapParts>
            <tt:value ref="ROOT.SCRAPPARTS"/>
          </ScrapParts>
          <MissingParts>
            <tt:value ref="ROOT.MISSINGPARTS"/>
          </MissingParts>
          <TargetProcessingTimePerPiece>
            <tt:value ref="ROOT.TARGETPROCESSINGTIMEPERPIECE"/>
          </TargetProcessingTimePerPiece>
          <ProcessingTime>
            <tt:value ref="ROOT.PROCESSINGTIME"/>
          </ProcessingTime>
          <SetupTime>
            <tt:value ref="ROOT.SETUPTIME"/>
          </SetupTime>
          <MeasuringTime>
            <tt:value ref="ROOT.MEASURINGTIME"/>
          </MeasuringTime>
          <OperationStart>
            <tt:value ref="ROOT.OPERATIONSTART"/>
          </OperationStart>
          <OperationEnd>
            <tt:value ref="ROOT.OPERATIONEND"/>
          </OperationEnd>
          <PartWeight>
            <tt:value ref="ROOT.PARTWEIGHT"/>
          </PartWeight>
          <PartArea>
            <tt:value ref="ROOT.PARTAREA"/>
          </PartArea>
          <PartLength>
            <tt:value ref="ROOT.PARTLENGTH"/>
          </PartLength>
          <PartWidth>
            <tt:value ref="ROOT.PARTWIDTH"/>
          </PartWidth>
          <Assembly>
            <tt:value ref="ROOT.ASSEMBLY"/>
          </Assembly>
          <DataExt>
            <tt:value ref="ROOT.DATAEXT"/>
          </DataExt>
          <OrderNoExt>
            <tt:value ref="ROOT.ORDERNOEXT"/>
          </OrderNoExt>
          <CollectiveOrder>
            <tt:value ref="ROOT.COLLECTIVEORDER"/>
          </CollectiveOrder>
          <ErpID>
            <tt:value ref="ROOT.ERPID"/>
          </ErpID>

          <QuantityReports tt:ref="ROOT.QUANTITYREPORTS">
            <QuantityReport>
              <ReportingTime>
                <tt:value ref="QUANTITYREPORT.REPORTINGTIME"/>
              </ReportingTime>
              <ProcessedParts>
                <tt:value ref="QUANTITYREPORT.PROCESSEDPARTS"/>
              </ProcessedParts>
              <ScrapParts>
                <tt:value ref="QUANTITYREPORT.SCRAPPARTS"/>
              </ScrapParts>
              <MissingParts>
                <tt:value ref="QUANTITYREPORT.MISSINGPARTS"/>
              </MissingParts>
              <BatchNo>
                <tt:value ref="QUANTITYREPORT.BATCHNO"/>
              </BatchNo>
              <WorkPlace>
                <tt:value ref="QUANTITYREPORT.WORKPLACE"/>
              </WorkPlace>
              <ReportedBy>
                <tt:value ref="QUANTITYREPORT.REPORTEDBY"/>
              </ReportedBy>
              <Terminal>
                <tt:value ref="QUANTITYREPORT.TERMINAL"/>
              </Terminal>
            </QuantityReport>
          </QuantityReports>

          <Consumption tt:ref="ROOT.CONSUMPTION">
            <tt:loop name="item" ref="RESOURCECONSUMPTION">
              <ResourceConsumption>
                <ResourceDescription>
                  <tt:value ref="$item.RESOURCEDESCRIPTION"/>
                </ResourceDescription>
                <ResourceNote>
                  <tt:value ref="$item.RESOURCENOTE"/>
                </ResourceNote>
                <ResourceCategory>
                  <tt:value ref="$item.RESOURCECATEGORY"/>
                </ResourceCategory>
                <Consumption>
                  <tt:value ref="$item.CONSUMPTION"/>
                </Consumption>
                <UnitOfConsumption>
                  <tt:value ref="$item.UNITOFCONSUMPTION"/>
                </UnitOfConsumption>
                <Rawmaterial>
                  <tt:value ref="$item.RAWMATERIAL"/>
                </Rawmaterial>

                <Dimensions>
                  <Length>
                    <tt:value ref="$item.DIMENSIONS.LENGTH"/>
                  </Length>
                  <Width>
                    <tt:value ref="$item.DIMENSIONS.WIDTH"/>
                  </Width>
                  <Thickness>
                    <tt:value ref="$item.DIMENSIONS.THICKNESS"/>
                  </Thickness>
                  <Unit>
                    <tt:value ref="$item.DIMENSIONS.UNIT"/>
                  </Unit>

                </Dimensions>
              </ResourceConsumption>
            </tt:loop>
          </Consumption>



        </Operation>
      </ProductionOperationFeedback>
    </PPSExport>
  </tt:template>

</tt:transform>

转化的输入结构(部分截图)如下: 

 STRAN的调用方式如下:

  data: lo_cx_st_match_element type ref to cx_st_match_element,
        lv_message type string.   
 data: ls_input type ty_order.
 TRY.
        CALL TRANSFORMATION zxxx
             SOURCE XML lv_xml
             RESULT root =  ls_input.

      CATCH cx_st_match_element INTO lo_cx_st_match_element.
        lv_message = lo_cx_st_match_element->get_text( ).

        ev_type = 'E'.
        ev_mess = '传入XML文件解析有误'.

    ENDTRY.

 方法二:调用SAP方法按照node来解析xml

 if lv_xml is not initial.

    try.
*        CALL TRANSFORMATION zmes004_input
*             SOURCE XML lv_xml
*             RESULT root =  ls_input.
        l_ixml = cl_ixml=>create( ).
        l_streamfactory = l_ixml->create_stream_factory( ).

        l_istream = l_streamfactory->create_istream_string(
                                       string = lv_xml ).
        l_document = l_ixml->create_document( ).
        l_parser = l_ixml->create_parser(
                             stream_factory = l_streamfactory
                             istream        = l_istream
                             document       = l_document ).

        if l_parser->parse( ) ne 0.
          if l_parser->num_errors( ) ne 0.
            l_parse_error = l_parser->get_error( index = l_index ).
            ev_type = 'E'.
            ev_mess = 'xml解析有误'.
          endif.
        endif.

        if l_parser->is_dom_generating( ) eq 'X'.
          perform frm_process_dom_bg using l_document
                               changing ls_input.
        endif.
      catch cx_st_match_element into lo_cx_st_match_element.
        lv_message = lo_cx_st_match_element->get_text( ).

        ev_type = 'E'.
        ev_mess = '传入XML文件解析有误'.

    endtry.
form frm_process_dom_bg using l_document type ref to if_ixml_document
                   changing ps_stru type ty_order.
  data: lo_node      type ref to if_ixml_node,
        lo_iterator  type ref to if_ixml_node_iterator.
  data: lo_nodemap type ref to if_ixml_named_node_map.
  data: lo_nodelist2   type ref to if_ixml_node_list,
        lo_nodelist3   type ref to if_ixml_node_list,
        lo_node2      type ref to if_ixml_node,
        lo_node3      type ref to if_ixml_node.
  data: lv_name_node type string.
  data: lv_name type char30,
        lv_value type string.
  data: lv_count type i,
        lv_index type sy-index,
        lv_prefix type string.
  data lo_attr type ref to if_ixml_node.
  field-symbols: <fs_field>,
                 <fs_field1>,
                 <fs_field2>.
  data: ls_quantityreport type ty_report.
  data: ls_resourceconsumption type ty_resourceconsumption,
        lt_resourceconsumption type table of ty_resourceconsumption.
  data: ls_dimensions type ty_dimensions.


  lo_node ?= l_document.

  check not lo_node is initial.

  lo_iterator  = lo_node->create_iterator( ).
  lo_node = lo_iterator->get_next( ).

  data lv_type type i.
  while not lo_node is initial.
    lv_type = lo_node->get_type( ).
    case lv_type.
      when if_ixml_node=>co_node_element.
        lv_name_node  = lo_node->get_name( ).
        lv_name = lv_name_node.
        translate lv_name to upper case.

        if lv_name = 'OPERATION'.

          lo_nodemap = lo_node->get_attributes( ).
          if not lo_nodemap is initial.
            lv_count = lo_nodemap->get_length( ).
            do lv_count times.
              lv_index  = sy-index - 1.
              lo_attr   = lo_nodemap->get_item( lv_index ).
              lv_name_node   = lo_attr->get_name( ).
              lv_name = lv_name_node.
              translate lv_name to upper case.
              assign component lv_name of structure ps_stru to <fs_field>.
              lv_prefix = lo_attr->get_namespace_prefix( ).
              lv_value  = lo_attr->get_value( ).
              if <fs_field> is assigned.
                if lv_value is not initial.
                  <fs_field> = lv_value.
                endif.
              endif.
              if lv_name = 'ORDERNO'.
                exit.
              endif.
            enddo.
          endif.
        elseif lv_name = 'REPORTINGTIME' or lv_name = 'PROCESSEDPARTS' or
                lv_name = 'SCRAPPARTS' or lv_name = 'MISSINGPARTS' or
                lv_name = 'BATCHNO' or lv_name = 'WORKPLACE' or
                lv_name = 'REPORTEDBY' or lv_name = 'TERMINAL'.

          assign component lv_name of structure ls_quantityreport to <fs_field>.
        elseif lv_name = 'RESOURCEDESCRIPTION' or lv_name = 'RESOURCENOTE' or
                lv_name = 'RESOURCECATEGORY' or lv_name = 'CONSUMPTION' or
                lv_name = 'UNITOFCONSUMPTION' or lv_name = 'RAWMATERIAL' .

          assign component lv_name of structure ls_resourceconsumption to <fs_field>.
        elseif lv_name = 'LENGTH' or lv_name = 'WIDTH' or
               lv_name = 'THICKNESS' or lv_name = 'UNIT'.
          assign component lv_name of structure ls_dimensions to <fs_field>.
        else.
          assign component lv_name of structure ps_stru to <fs_field>.
        endif.
      when if_ixml_node=>co_node_text or
           if_ixml_node=>co_node_cdata_section.

        lv_value = lo_node->get_value( ).
        if <fs_field> is assigned.
          <fs_field> = lv_value.
        endif.
        if lv_name = 'UNIT'..
          ls_resourceconsumption-dimensions = ls_dimensions.
          append ls_resourceconsumption to lt_resourceconsumption.
          clear ls_resourceconsumption.
          clear ls_dimensions.
        endif.
    endcase.
    clear:lo_node,lo_nodemap,lo_attr,lv_name_node.
    clear:lv_prefix,lv_value,lv_count,lv_index.
    lo_node = lo_iterator->get_next( ).

  endwhile.

  clear:lo_node,lo_iterator.
  ps_stru-quantityreports-quantityreport = ls_quantityreport.
  ps_stru-consumption-resourceconsumption = lt_resourceconsumption.
  unassign <fs_field>.
endform.                    "process_dom

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/713852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.5 编写自定位ShellCode弹窗

在笔者上一篇文章中简单的介绍了如何运用汇编语言编写一段弹窗代码&#xff0c;虽然简易ShellCode可以被正常执行&#xff0c;但却存在很多问题&#xff0c;由于采用了硬编址的方式来调用相应API函数的&#xff0c;那么就会存在一个很大的缺陷&#xff0c;如果操作系统的版本不…

提取图像中的文本信息(Tesseract OCR 和 pytesseract)

环境准备 安装Tesseract&#xff1a;点这里参考本人博客 下载第三方库 pip install Pytesseract这个库只自带了一个英语的语言包&#xff0c;这个时候如果我们图片中有对中文或者其他语言的识别需求&#xff0c;就需要去下载其他语言包 下载其他语言包 进入官网以后进入Tra…

MyBatisPlus基础知识

一、MyBatisPlus 1.MyBatisPlus入门案例与简介 这一节我们来学习下MyBatisPlus的入门案例与简介&#xff0c;这个和其他课程都不太一样&#xff0c;其他的课程都是先介绍概念&#xff0c;然后再写入门案例。而对于MyBatisPlus的学习&#xff0c;我们将顺序做了调整&#xff0…

STM32——MCU简单介绍

文章目录 一、单片机基础简介1.MCU简介&#xff08;1&#xff09;MCU的组成&#xff08;2&#xff09;常见的MCU 2.STM32简介&#xff08;1&#xff09;STM32&STM8产品型号--各个字母的含义 3.如何查手册&#xff08;1&#xff09;数据手册芯片信息总线框图时钟树内存映射 …

Java面试题及答案整理( 金九银十最新版,持续更新)

最近可能有点闲的慌&#xff0c;没事就去找面试面经&#xff0c;整理了一波面试题。我大概是分成了 Java 基础、中级、高级&#xff0c;分布式&#xff0c;Spring 架构&#xff0c;多线程&#xff0c;网络&#xff0c;MySQL&#xff0c;Redis 缓存&#xff0c;JVM 相关&#xf…

【vue】使用uni-indexed-list组件点击获取下标详情

问题描述 使用uniapp自带的uni-indexed-list组件&#xff0c;点击索引只能获取到点击的名称&#xff0c;不能获取其他信息 解决方案&#xff1a; uni-indexed-list组件1.2.1版本 对uni-indexed-list组件代码进行修改,示例如下: 找到setList函数&#xff0c;对内部逻辑赋值就…

二叉树 — 多叉转二叉树

题目&#xff1a; 将一棵多叉树&#xff0c;转换成二叉树&#xff0c;在通过这个二叉树还原成多叉树。 分析 毫无疑问&#xff0c;多叉树的头结点也是转换的二叉树的头结点。 多叉树如下图所示&#xff1a; 转换成二叉树&#xff0c;则将多叉树所有的节点X&#xff0c;将X的孩…

MATLAB导入EXCEL表格数据画散点图

namexxxx.xlsx;%这里的xxxx是EXCEL文件的名字&#xff0c;而且需要将它和.m文件放在同一个文件夹下 axlsread(name,D2:D25); aa; bxlsread(name,I2:I25); bb; x[a,b]; cxlsread(name,E2:E25); cc; dxlsread(name,J2:J25); dd; y[c,d]; plot(x,y,b-o),grid on;%b-o是颜色和图案&…

linux 内核接口atomic_long_try_cmpxchg_acquire/release详解

linux 内核接口atomic_long_try_cmpxchg_acquire详解 1 atomic_long_try_cmpxchg_acquire/release1.1 atomic_long_try_cmpxchg_acquire1.2 atomic_long_try_cmpxchg_release 2 arch_atomic64_cmpxchg_acquire/release2.1 arch_atomic64_cmpxchg_acquire/release定义2.2 atomic…

移远通信携手中国电信等伙伴重磅发布5G NTN试验成果,共促卫星物联网产业发展

6月29日&#xff0c;在MWC上海展期间&#xff0c;以“5G云网新科技 数字经济新动能”为主题的2023中国电信5G/6G科技创新成果发布会顺利举行。 会上&#xff0c;中国电信联合合作伙伴重磅发布了多项科技创新成果和科技创新应用&#xff0c;作为中国电信在卫星物联网领域重要的合…

ArcGIS SDE空间数据库 镶嵌数据集白边压盖及不显示问题

首先&#xff0c;在Oracle SDE空间数据库中新建了镶嵌数据集(Mosaic Dataset) &#xff0c;这里通过程序导入影像数据以后出现了 影像不显示&#xff08;得放到很小比例尺才显示&#xff09;及影像之间互相压盖 第一&#xff0c;解决影像互相压盖问题 在Calalog中右键镶嵌数据…

操作系统6——文件管理

本系列博客重点在深圳大学操作系统课程的核心内容梳理&#xff0c;参考书目《计算机操作系统》&#xff08;有问题欢迎在评论区讨论指出&#xff0c;或直接私信联系我&#xff09;。 梗概 本篇博客主要介绍操作系统第七章文件管理和第八章磁盘储存器的管理的相关知识。 目录 …

智谱AI-算法实习生(知识图谱方向)实习面试记录

岗位描述 没错和我的经历可以说是match得不能再match了&#xff0c;但是还是挂了hh。 面试内容 给我面试的是唐杰老师的博士生&#xff0c;方向是社交网络数据挖掘&#xff0c;知识图谱。不cue名了&#xff0c;态度很友好的 &#xff0c;很赞。 date&#xff1a;6.28 Q1 自…

【算法之双指针I】leetcode344.反转字符串

344.反转字符串 力扣题目链接 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须**原地修改输入数组**、使用 O(1) 的额外空间解决这一问题。 输入&#xff1a;s ["h…

【代理服务器】Squid代理服务器应用

目录 一、Squid代理服务器1.1代理的工作机制1.2代理服务器的概念1.3代理服务器的作用1.4Squid 代理的类型 二、安装Squid服务2.1编译安装Squid2.2修改 Squid 的配置文件2.3Squid运行控制2.4创建Squid服务脚本2.5 构建传统代理服务器2.6更改防火墙规则2.7验证 三、构建透明代理服…

Keil MDK 5 仿真STM32F4报错no ‘read‘ permission

问题描述 MDK软件模拟仿真提示没有读写权限&#xff0c;只能单步运行。error提示&#xff1a; *** error 65: access violation at 0x40023C00 : no read permission 关于Keil MDK 5 仿真STM32F4报错no ‘read’ permission的解决方法 Vision 调试器为所有 ARM7、ARM9、Corte…

怎样在文章末尾添加尾注(将尾注的数字变为方括号加数字)

在进行文章编写或者需要添加注解时&#xff0c;需要进行尾注的添加&#xff0c;下面将详细说明如何进行尾注的添加 操作 首先打开需要进行添加尾注的文档&#xff0c;将光标移动至需要进行添加尾注的文字后。 紧接着在上方工具栏中&#xff0c;选择引用&#xff0c;在引用页…

4.FreeRTOS系统配置文件详解(FreeRTOSConfig.h)

目录 一、基础配置选项 二、内存分配相关定义 三、钩子函数的相关定义 四、运行时间和任务状态统计相关定义 五、软件定时器相关配置 FreeRTOSConfig.h配置文件的作用&#xff1a; 对FreeRTOS进行功能配合和裁剪&#xff0c;以及API函数的使能 对于FreeRTOS配置文件主要…

如果制作投票选举投票制作制作一个投票在线制作投票

用户在使用微信投票的时候&#xff0c;需要功能齐全&#xff0c;又快捷方便的投票小程序。 而“活动星投票”这款软件使用非常的方便&#xff0c;用户可以随时使用手机微信小程序获得线上投票服务&#xff0c;很多用户都很喜欢“活动星投票”这款软件。 “活动星投票”小程序在…

CORS如何实现跨域(前端+后端代码实例讲解)

书接上回&#xff0c;上一篇文章讲解了用 jsonp 来解决跨域问题&#xff0c;这篇文章讲解另外一种方法也可以解决跨域问题&#xff0c;那就是CORS&#xff08;跨源资源共享&#xff09;。 什么是CORS&#xff1f; 下面是官方的解释&#xff1a;跨源资源共享&#xff08;CORS&a…