如何通过JSON。解析来自URL的字符串(React Native)

时间:2018-10-30 16:35:15

标签: javascript json string react-native fetch

我有一个URL,该字符串包含我要进行JSON解析的字符串 (我是React native的新手。)

这是URL中包含字符串-

的一部分
<string>[{"Song_ID":"11","Song_Name":"The Doors - People","Song_File":"http://myurl.com/songs/The_Doors_People.mp3","Image":"http://myurl.com/images/The_Doors.jpg"},{"Song_ID":"12","Song_Name":"Smashing Pumpkins - Porcelina","Song_File":"http://myurl.com/songs/Smashing_Pumpkins_Porcelina.mp3","Image":"http://myurl.com/images/Mellon_Collie.jpg"},]</string>

这是代码,我相信提取存在问题。 dataSource: JSON.parse(responseJson)不起作用。

const URL =
  "http://mobile.domain.com/site/WebService.asmx/SongsList";


export default class FetchExample extends React.Component {
  static navigationOptions = {
    title: "Json Data"
  };
  constructor(props) {
    super(props);
    this.state = { isLoading: true };
  }

  componentDidMount() {
    return fetch(URL)
      .then(response => response.json())
      .then(responseJson => {
        this.setState(
          {
            isLoading: false,
            dataSource: JSON.parse(responseJson) // doesn't work
          },
          function() {}
        );
      })
      .catch(error => {
        console.error(error);
      });
  }

我尝试了dataSource: JSON.stringify(responseJson),但是它也没有做。 渲染代码-(我希望这部分是-data={this.state.dataSource}

   render(){

    if(this.state.isLoading){
      return(
        <View style={{flex: 1, padding: 20}}>
          <ActivityIndicator/>
        </View>
      )
    }

    return(
      <View style={{flex: 1, paddingTop:20}}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) => <Text>{item.Song_ID}, {item.Song_Name}</Text>}
          keyExtractor={({id}, index) => id} // this part with the "id" and "index" I dont understand (the index in my code is fade)
        />
      </View>
    );
  }
}

它向我显示错误:“ JSON解析错误:无法识别的令牌'<'”。

2 个答案:

答案 0 :(得分:2)

  

它向我显示错误:“ JSON解析错误:无法识别的令牌'<'”。

这意味着您要解析的不是JSON。因此,您需要使用浏览器的“网络”标签来查看其内容。

如果您的问题确实存在:

[{"Song_ID":"11","Song_Name":"The Doors - People","Song_File":"http://myurl.com/songs/The_Doors_People.mp3","Image":"http://myurl.com/images/The_Doors.jpg"},{"Song_ID":"12","Song_Name":"Smashing Pumpkins - Porcelina","Song_File":"http://myurl.com/songs/Smashing_Pumpkins_Porcelina.mp3","Image":"http://myurl.com/images/Mellon_Collie.jpg"},]

然后有两个问题:

  1. 开头的<string>和结尾的</string>(并且适合您的错误消息),并且

  2. 在JSON中,数组中不能包含结尾逗号。

这是正确的JSON版本:

[{"Song_ID":"11","Song_Name":"The Doors - People","Song_File":"http://myurl.com/songs/The_Doors_People.mp3","Image":"http://myurl.com/images/The_Doors.jpg"},{"Song_ID":"12","Song_Name":"Smashing Pumpkins - Porcelina","Song_File":"http://myurl.com/songs/Smashing_Pumpkins_Porcelina.mp3","Image":"http://myurl.com/images/Mellon_Collie.jpg"}]

另一种可能性是,您根本没有得到自己认为的JSON,而是从服务器以HTML格式(给定<字符)发出了一条错误消息。 (HTML很有可能报告错误,请参阅下面的#4。)

但是您还有另外两个问题:

  1. 您正在尝试双重解析JSON:

    componentDidMount() {
      return fetch(URL)
        .then(response => response.json()) // <=== Parses the JSON
        .then(responseJson => {
          this.setState(
            {
              isLoading: false,
              dataSource: JSON.parse(responseJson) // <=== Tries to parse it again
            },
            function() {}
          );
        })
        .catch(error => {
          console.error(error);
        });
    }
    

    仅解析一次。

  2. 您的代码需要检查response.ok。您并不是唯一一个错过这张支票的人,这很常见,人们都错过了这张支票,以至于我wrote it up on my anemic little blog

所以(请参阅***条评论):

componentDidMount() {
  return fetch(URL)
    .then(response => {
        if (!response.ok) {                      // *** Check errors
            throw new Error(                     // ***
                "HTTP status " + response.status // ***
            );                                   // ***
        }                                        // ***
        return response.json();                  // *** Parse the JSON (once)
    })
    .then(dataSource => {                        // *** More accurate name
      this.setState(
        {
          isLoading: false,
          dataSource                             // *** Use the parsed data
        },
        function() {}
      );
    })
    .catch(error => {
      console.error(error);
    });
}

在评论中您说过:

  

我无法删除该标签,它来自c#url WebService.asmx

您应该能够在WebService.asmx中对其进行修复。 ASP.net绝对可以产生有效的JSON。否则,您将无法直接将其解析为JSON。

但是-而且我建议这样做-如果绝对必要,您可以对字符串进行预处理以处理我指出的两个问题:

componentDidMount() {
  return fetch(URL)
    .then(response => {
        if (!response.ok) {                      // *** Check errors
            throw new Error(                     // ***
                "HTTP status " + response.status // ***
            );                                   // ***
        }                                        // ***
        return response.text();                  // *** Read the TEXT of the response
    })
    .then(dataSourceText => {                    // *** More accurate name
      // *** Remove the invalid parts and parse it
      const dataSource = JSON.parse(
        dataSourceText.match(/^<string>(.*),]<\/string>$/)[1] + "]"
      );
      this.setState(
        {
          isLoading: false,
          dataSource                             // *** Use the parsed data
        },
        function() {}
      );
    })
    .catch(error => {
      console.error(error);
    });
}

答案 1 :(得分:0)

似乎问题在于响应包含标签<string></string>。我认为,如果您将其删除,则应首先使用。

就像这个question