如何让json从icecast变成反应组件?

时间:2016-11-04 17:01:23

标签: json reactjs xmlhttprequest cors fetch

我一直在试图弄清楚为什么这个json不利于我。根据jsonlint,它不是有效的json。我怎么能把它转换成有效的json?我尝试过使用fetch和xhr。我正在解决这个问题,现在我很难过。我搜索过但不确定我发现了类似的东西。

我的反应成分方法:

apt-get install ruby
apt-get install ruby-dev

我的冰球json。

  fetchData() {

      var url = 'http://192.168.1.10:8000/status-json.xsl'
      var self = this;
      fetch(url, {
          'mode': 'no-cors'
      })
          .then(function(response) {
              return response.json()
          }).then(function(json) {
              console.log('parsed json', json)
          }).
      catch (function(ex) {
          console.log('parsing failed', ex)
      })
      xhr({
          url: url,
          dataType: 'jsonp',
          headers: {
              "Content-Type": "application/json",
              'Access-Control-Allow-Origin': "*"
          },
      }, function(err, data) {
          var body = JSON.parse(data);
          console.log(body)
          self.setState({
              data: body,
          });
      });
  },

浏览器控制台出错:

{
icestats: {
admin: "",
host: "",
location: "",
server_id: "Icecast 2.4.1",
server_start: "Tue, 28 Jun 2016 14:41:06 -0500",
server_start_iso8601: "2016-06-28T14:41:06-0500",
source: [
{
audio_info: "bitrate=39",
bitrate: 39,
genre: "court",
listener_peak: 3,
listeners: 0,
listenurl: "http://192.168.1.10/RADIO-2nd-1",
server_description: "RADIO-2nd-1",
server_name: "RADIO-2nd-1",
server_type: "audio/mpeg",
server_url: "http://192.168.1.176:81",
stream_start: "Wed, 19 Oct 2016 17:06:24 -0500",
stream_start_iso8601: "2016-10-19T17:06:24-0500",
dummy: null
},
{
audio_info: "bitrate=75",
bitrate: 75,
genre: "court",
listener_peak: 0,
listeners: 0,
listenurl: "http://192.168.1.10/RADIO-2nd-2",
server_description: "RADIO-2nd-2",
server_name: "RADIO-2nd-2",
server_type: "audio/mpeg",
server_url: "http://192.168.1.176:82",
stream_start: "Wed, 12 Oct 2016 19:24:26 -0500",
stream_start_iso8601: "2016-10-12T19:24:26-0500",
dummy: null
},
{
audio_info: "bitrate=39",
bitrate: 39,
genre: "court",
listener_peak: 7,
listeners: 4,
listenurl: "http://192.168.1.10/RADIO-5th-1",
server_description: "RADIO-5th-1",
server_name: "RADIO-5th-1",
server_type: "audio/mpeg",
server_url: "http://192.168.1.83",
stream_start: "Wed, 19 Oct 2016 23:43:45 -0500",
stream_start_iso8601: "2016-10-19T23:43:45-0500",
dummy: null
},
{
audio_info: "bitrate=39",
bitrate: 39,
genre: "court",
listener_peak: 0,
listeners: 0,
listenurl: "http://192.168.1.10/RADIOBK-4th-1",
server_description: "RADIOBK-4th-1",
server_name: "RADIOBK-4th-1",
server_type: "audio/mpeg",
server_url: "http://192.168.1.10",
stream_start: "Wed, 02 Nov 2016 14:00:42 -0500",
stream_start_iso8601: "2016-11-02T14:00:42-0500",
dummy: null
},
{
audio_info: "bitrate=39",
bitrate: 39,
genre: "court",
listener_peak: 2,
listeners: 0,
listenurl: "http://192.168.1.10/RADIO-1st-1",
server_description: "RADIO-1st-1",
server_name: "RADIO-1st-1",
server_type: "audio/mpeg",
server_url: "http://156.127.4.72",
stream_start: "Tue, 18 Oct 2016 08:06:39 -0500",
stream_start_iso8601: "2016-10-18T08:06:39-0500",
dummy: null
},
{
audio_info: "bitrate=39",
bitrate: 39,
genre: "court",
listener_peak: 6,
listeners: 1,
listenurl: "http://192.168.1.10/RADIO-2nd-1",
server_description: "RADIO-2nd-1",
server_name: "RADIO-2nd-1",
server_type: "audio/mpeg",
server_url: "http://156.127.4.62",
stream_start: "Tue, 18 Oct 2016 09:56:00 -0500",
stream_start_iso8601: "2016-10-18T09:56:00-0500",
dummy: null
},
{
audio_info: "bitrate=39",
bitrate: 39,
genre: "court",
listener_peak: 3,
listeners: 0,
listenurl: "http://192.168.1.10/RADIO-3rd-1",
server_description: "RADIO-3rd-1",
server_name: "RADIO-3rd-1",
server_type: "audio/mpeg",
server_url: "http://156.127.82.80",
stream_start: "Wed, 12 Oct 2016 19:24:26 -0500",
stream_start_iso8601: "2016-10-12T19:24:26-0500",
dummy: null
},
{
audio_info: "bitrate=39",
bitrate: 39,
genre: "court",
listener_peak: 0,
listeners: 0,
listenurl: "http://192.168.1.10/RADIO-3rd-2",
server_description: "RADIO-3rd-2",
server_name: "RADIO-3rd-2",
server_type: "audio/mpeg",
server_url: "http://156.127.82.81",
stream_start: "Wed, 12 Oct 2016 19:24:26 -0500",
stream_start_iso8601: "2016-10-12T19:24:26-0500",
dummy: null
}
]
}
}

1 个答案:

答案 0 :(得分:1)

我认为问题是应引用icestats之类的JSON密钥:"icestats": {...

尝试将status-json.xsl替换为:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="xml2json.xslt"/>
<xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="application/json"/>
<xsl:strip-space elements="*"/>

<!-- override imported transform variable to enable output -->
<xsl:variable name="output">true</xsl:variable>

<!-- hide certain nodes from all sources -->
<xsl:template match="icestats/source/max_listeners" />
<xsl:template match="icestats/source/public" />
<xsl:template match="icestats/source/source_ip" />
<xsl:template match="icestats/source/slow_listeners" />
<xsl:template match="icestats/source/*[contains(name(), 'total_bytes')]" />
<xsl:template match="icestats/source/user_agent" >
    <!-- user_agent is most of the time the last node in a mount, 
         if we just delete it, then we will malform the output, 
         so special handling applies. -->
    <xsl:if test="following-sibling::*"></xsl:if>
    <xsl:if test="not(following-sibling::*)">"dummy":null}</xsl:if> 
</xsl:template>

<!-- hide certain global nodes -->
<xsl:template match="icestats/sources" />
<xsl:template match="icestats/clients" />
<xsl:template match="icestats/stats" />
<xsl:template match="icestats/listeners" />
<xsl:template match="node()[contains(name(), 'connections')]" />

</xsl:stylesheet>

同时将此文件xml2json.xslt添加到Icecast网站目录:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="application/json"/>
    <xsl:strip-space elements="*"/>
  <!--default to no output-->
  <xsl:variable name="output">false</xsl:variable>

  <!--constant-->
  <xsl:variable name="d">0123456789</xsl:variable>

  <!-- ignore document text -->
  <xsl:template match="text()[preceding-sibling::node() or following-sibling::node()]"/>

  <!-- string -->
  <xsl:template match="text()">
    <xsl:call-template name="escape-string">
      <xsl:with-param name="s" select="."/>
    </xsl:call-template>
  </xsl:template>

  <!-- Main template for escaping strings; used by above template and for object-properties 
       Responsibilities: placed quotes around string, and chain up to next filter, escape-bs-string -->
  <xsl:template name="escape-string">
    <xsl:param name="s"/>
    <xsl:text>"</xsl:text>
    <xsl:call-template name="escape-bs-string">
      <xsl:with-param name="s" select="$s"/>
    </xsl:call-template>
    <xsl:text>"</xsl:text>
  </xsl:template>

  <!-- Escape the backslash (\) before everything else. -->
  <xsl:template name="escape-bs-string">
    <xsl:param name="s"/>
    <xsl:choose>
      <xsl:when test="contains($s,'\')">
        <xsl:call-template name="escape-quot-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'\'),'\\')"/>
        </xsl:call-template>
        <xsl:call-template name="escape-bs-string">
          <xsl:with-param name="s" select="substring-after($s,'\')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="escape-quot-string">
          <xsl:with-param name="s" select="$s"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- Escape the double quote ("). -->
  <xsl:template name="escape-quot-string">
    <xsl:param name="s"/>
    <xsl:choose>
      <xsl:when test="contains($s,'&quot;')">
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'&quot;'),'\&quot;')"/>
        </xsl:call-template>
        <xsl:call-template name="escape-quot-string">
          <xsl:with-param name="s" select="substring-after($s,'&quot;')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="$s"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- Replace tab, line feed and/or carriage return by its matching escape code. Can't escape backslash
       or double quote here, because they don't replace characters (&#x0; becomes \t), but they prefix 
       characters (\ becomes \\). Besides, backslash should be seperate anyway, because it should be 
       processed first. This function can't do that. -->
  <xsl:template name="encode-string">
    <xsl:param name="s"/>
    <xsl:choose>
      <!-- tab -->
      <xsl:when test="contains($s,'&#x9;')">
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'&#x9;'),'\t',substring-after($s,'&#x9;'))"/>
        </xsl:call-template>
      </xsl:when>
      <!-- line feed -->
      <xsl:when test="contains($s,'&#xA;')">
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'&#xA;'),'\n',substring-after($s,'&#xA;'))"/>
        </xsl:call-template>
      </xsl:when>
      <!-- carriage return -->
      <xsl:when test="contains($s,'&#xD;')">
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'&#xD;'),'\r',substring-after($s,'&#xD;'))"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise><xsl:value-of select="$s"/></xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- number (no support for javascript mantissa) -->
  <xsl:template match="text()[not(string(number())='NaN' or
                       (starts-with(.,'0' ) and . != '0'))]">
    <xsl:value-of select="."/>
  </xsl:template>

  <!-- boolean, case-insensitive -->
  <xsl:template match="text()[translate(.,'TRUE','true')='true']">true</xsl:template>
  <xsl:template match="text()[translate(.,'FALSE','false')='false']">false</xsl:template>

  <!-- objects and arrays -->
  <xsl:template match="*" name="base">
    <xsl:choose>
      <!-- complete array -->
      <xsl:when test="(count(../*[name(current())=name()])=count(../*)) and count(../*[name(current())=name()])&gt;1">
        <xsl:variable name="el" select="name()"/>
        <xsl:if test="not(following-sibling::*[name()=$el])">
          <xsl:text>[</xsl:text>
          <xsl:for-each select="../*[name()=$el]">
            <xsl:if test="position()!=1">,</xsl:if>
            <xsl:choose>
              <xsl:when test="not(child::node())">
                <xsl:text>null</xsl:text>
              </xsl:when>
              <xsl:otherwise>
                <xsl:apply-templates select="child::node()"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each>
          <xsl:text>]</xsl:text>
        </xsl:if>
      </xsl:when>

      <!-- partial array -->
      <xsl:when test="count(../*[name(current())=name()])&gt;1">
        <xsl:if test="not(preceding-sibling::*)">{</xsl:if>
        <xsl:variable name="el" select="name()"/>
        <xsl:if test="not(following-sibling::*[name()=$el])">
          <xsl:call-template name="escape-string">
            <xsl:with-param name="s" select="$el"/>
          </xsl:call-template>
          <xsl:text>:[</xsl:text>
          <xsl:for-each select="../*[name()=$el]">
            <xsl:if test="position()!=1">,</xsl:if>
            <xsl:choose>
              <xsl:when test="not(child::node())">
                <xsl:text>null</xsl:text>
              </xsl:when>
              <xsl:otherwise>
                <xsl:apply-templates select="child::node()"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each>
          <xsl:text>]</xsl:text>
          <xsl:if test="following-sibling::*">,</xsl:if>
        </xsl:if>
        <xsl:if test="not(following-sibling::*)">}</xsl:if>
      </xsl:when>

      <!-- object -->
      <xsl:otherwise>
        <xsl:if test="not(preceding-sibling::*)">{</xsl:if>
        <xsl:call-template name="escape-string">
          <xsl:with-param name="s" select="name()"/>
        </xsl:call-template>
        <xsl:text>:</xsl:text>
        <!-- check type of node -->
        <xsl:choose>
            <!-- null nodes -->
            <xsl:when test="count(child::node())=0">null</xsl:when>
            <!-- other nodes -->
            <xsl:otherwise>
                <xsl:apply-templates select="child::node()"/>
            </xsl:otherwise>
          </xsl:choose>
          <!-- end of type check -->
          <xsl:if test="following-sibling::*">,</xsl:if>
        <xsl:if test="not(following-sibling::*)">}</xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- convert root element to an anonymous container -->
  <xsl:template match="/">
    <xsl:if test="$output='true'">
      <xsl:apply-templates select="node()"/>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

请检查您的JSON URL(http://192.168.1.10:8000/status-json.xsl)是否正常工作,例如尝试在浏览器中打开它,因为此错误:

http://192.168.1.10:8000/status-json.xsl net::ERR_EMPTY_RESPONSE_createXHR

表示回复为空。

以下是我的一个互联网收音机的一个工作示例,它不是React(jQuery),但它的工作方式应该相同。

注意:

  1. 您不必解析响应JSON.parse(data),因为返回的数据是JSON格式。
  2. 我的Icecast实例配置为使用此标头进行响应:
  3. Access-Control-Allow-Origin: *
    Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type
    Access-Control-Allow-Methods: GET, OPTIONS, HEAD
    

    允许我们绕过CORS限制。将此行添加到您的Icecast配置文件中:

    <icecast>
        <http-headers>
            <header name="Access-Control-Allow-Origin" value="*" />
            <header name="Access-Control-Allow-Headers" value="Origin, Accept, X-Requested-With, Content-Type, If-Modified-Since" />
            <header name="Access-Control-Allow-Methods" value="GET, OPTIONS, HEAD" />
        </http-headers>
    ...
    

    这是我的片段(它输出当前曲目标题):

    &#13;
    &#13;
    jQuery.get("http://stream.indiecore.fm:8000/status-json.xsl", {}, function(response){
      console.log("Now playing: ", response.icestats.source[0]['title']);
    })
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    &#13;
    &#13;
    &#13;