【问题标题】:Determine whether data is json or string and perform logic basing o that确定数据是 json 还是 string 并根据它执行逻辑
【发布时间】:2018-08-06 12:57:38
【问题描述】:

基本上我正在尝试确定服务器返回的是 json 还是字符串

然后转换该 json 并在循环中显示它的每个元素,或者只显示那个字符串。

我想要达到这样的目标:

  • 发送带有一些数据的发布请求

  • 如果 post bodyText 包含 { 和 } 则将其解析为 json 并在 html 中绘制 <li>

其他

  • 只需打印 bodyText。

new Vue({
    el: '#app',
    data: {

            user: {
                UserLogin: 'test',
                UserEmail: 'test',
                UserPassword: 'test'
            },
            responseArr: []
        },
    methods: {
        submit() {
            this.$http.post('http://api.com/validate', this.user)
            .then(response => {
                return "OK";
            },
            error => {  
                    return error.bodyText; 
            })
            .then(data => {
                console.log(data);

                if (data.includes("{")) {
                    console.log("if");
                    data = JSON.parse(data);
                    const arr = [];
                    for (let key in data) {
                        arr.push(data[key]);
                    }
                    this.responseArr = arr;
                }
                else
                {
                    console.log("else");
                    const arr = [];
                    arr.push(data);
                    this.responseArr = arr;
                }
            }
            );
        },
    }
    });

<div id="errorList">
    <li v-for="element in responseArr">
        <div v-if="responseArr.includes('{')">
            <ul class="errorScope">
                <li v-for="nested_element in element">{{nested_element}}</li>
            </ul>
        </div>
        <div v-else>
             <li>{{element}}</li>
        </div>
<button v-on:click="submit">Submit</button>

【问题讨论】:

  • 你可以调用JSON.parse() 并在抛出异常时捕获异常。
  • @Pointy 我在“以前的版本”中尝试过,但最后由于某种原因我仍然无法正确地将数据注入到 html 中。例如 vue 不会刷新它。
  • 你可以用if (typeof data === "string")代替data.includes("{"),这意味着你有字符串并在if块中做JSON.parse(data)
  • {{元素}}

标签: javascript vue.js frontend


【解决方案1】:

在解析响应之前,响应始终是字符串。问题是您不知道响应是普通字符串,或者它是可解析的字符串。所以,你有两个选择。首先,是这样的:

...
.then(response => {
  let type = 'json'
  let data
  try {
    // try to parse the response text
    data = JSON.parse(response)
  } catch {
    // no, response is not parseable
    data = response
    type = 'string'
  }
  // here you know the type
  // and your data are prepared
})

或者,根据您用于 $http 调用的库,您还有第二个选项。也许这个库可以告诉你响应类型,是“text/plain”还是“application/json”。

PS:如果你不确定响应是否已经被解析,你可以这样检查:

if (response instanceof Object) {
  // response is already parsed json string,
  // so object or array
} else {
  // response is not parsed,
  // try to parse it or what
}

【讨论】:

    【解决方案2】:

    您可以使用 typeof 运算符来确定某物是否是 Javascript 对象 --

    let obj = {'age' : 30};
    if(typeof obj == "object"){
       // It's object
    }else if(typeof obj == 'string'){
       // It's String
    }
    

    【讨论】:

      【解决方案3】:

      下面是一种方法

      // HTML
      <div id="app">
        <h2>Todos:</h2>
        <ol>
          <input type="button"
                v-on:click="load()" value="load next">
          <h1 v-if="textResponse">{{textResponse}}</h1>
          <h1 v-if="loadNr==1" style="font-size: 0.8em">click again to load json}</h1>
          <li v-for="todo in todos">
            <label>
              <input type="checkbox"
                v-on:change="toggle(todo)"
                v-bind:checked="todo.done">
              <del v-if="todo.done">
                {{ todo.text }}
              </del>
              <span v-else>
                {{ todo.text }}
              </span>
            </label>
          </li>
        </ol>
      </div>
      
      // CSS
      body {
        background: #20262E;
        padding: 20px;
        font-family: Helvetica;
      }
      
      #app {
        background: #fff;
        border-radius: 4px;
        padding: 20px;
        transition: all 0.2s;
      }
      
      li {
        margin: 8px 0;
      }
      
      h2 {
        font-weight: bold;
        margin-bottom: 15px;
      }
      
      del {
        color: rgba(0, 0, 0, 0.3);
      }
      
      // JavaScript
      
      const requestText = 'request returned a text response';
      const requestJson = '[{"text":"Learn JavaScript","done":false},{"text":"Learn Vue","done":false},{"text":"Play around in JSFiddle","done":true},{"text":"Build something awesome","done":true}]';
      
      new Vue({
        el: "#app",
        data: {
          todos: [],
          textResponse: '',
          loadNr: 0
        },
        methods: {
          toggle: function(todo){
              todo.done = !todo.done
          },
          load: function(){
              let requestResponse;
            this.textResponse = '';
              if (!this.loadNr) {
              // simulate text
              requestResponse = requestText;
            } else {
              //  simulate json
              requestResponse = requestJson;
            }
      
            let json;
            try {
              if (typeof requestResponse === 'object') {
                  //  server sent already parsed json
                  this.todos = requestResponse;
              } else {
                  //  server sent json string
                  this.todos = JSON.parse(requestResponse);
              }
            } catch (error) {
              this.textResponse = requestResponse;
            }
            this.loadNr++;
          }
        }
      });
      

      Sample Fiddle

      【讨论】:

      • 我的意思是提供数据并位于服务器和前端之间的 api/service 可以返回 json。我很少处理 json 字符串。它几乎总是 json 对象,因为这就是中间 api 服务的制作方式。
      猜你喜欢
      相关资源
      最近更新 更多
      热门标签