2016-08-11 2 views
0

Прошу прощения за публикацию этого, но после стольких часов вытягивания волос я не могу больше продвинуться.JSON.parse со специальными читтерами

У меня есть JSON строку, которая возвращается ко мне как часть объекта JSON, как:

{ "name": "value", "artifact": "THE_JSON_STRING" } 

Я потянув артефакт, и используя JSON.parse отлично работает большую часть времени, но я столкнулся с проблемой, когда строка артефакта содержит перерывы/"и JSON.parse. Я перешел к множеству решений и попытался сделать что-то вроде всего, но я должен что-то сделать неправильно. Для простоты это мой код:

var str = '{ "name" : "This is some value \"escaped\""}'; 
str = str.replace(/\\"/g, 'x') 
var obj = JSON.parse(str); 

Любая помощь была бы очень признательна

https://fiddle.jshell.net/u428x1k7/2/

Редактировать

Я новичок в JavaScript, но я использую React с Redux, чтобы сделать вызов службы, чтобы получить мои данные. Тогда я пытаюсь использовать данные с помощью реквизита:

данных, поступающих от службы вызова:

{ 
    "id": "8b6df083-8f4f-440a-bc67-4c57bf0969bf", 
    "name": "My API ", 
    "description": "All APIs are added to this category if one is not specified", 
    "icon": "fa-university", 
    "services": [ 
     { 
      "id": "16e32cfd-b6e7-4c49-b5ef-ebb5456e6639", 
      "artifact": "{ \"swagger\": \"2.0\", \"info\": { \"version\": \"1.0.0\", \"title\": \"Swagger Petstore\", \"license\": { \"name\": \"MIT\" } }, \"host\": \"petstore.swagger.io\", \"basePath\": \"/v1\", \"schemes\": [ \"http\" ], \"consumes\": [ \"application/json\" ], \"produces\": [ \"application/json\" ], \"paths\": { \"/pets\": { \"get\": { \"summary\": \"List all pets\", \"operationId\": \"listPets\", \"tags\": [ \"pets\" ], \"parameters\": [ { \"name\": \"limit\", \"in\": \"query\", \"description\": \"How many items to return at one time (max 100)\", \"required\": false, \"type\": \"integer\", \"format\": \"int32\" } ], \"responses\": { \"200\": { \"description\": \"An paged array of pets\", \"headers\": { \"x-next\": { \"type\": \"string\", \"description\": \"A link to the next page of responses\" } }, \"schema\": { \"$ref\": \"#/definitions/Pets\" } }, \"default\": { \"description\": \"unexpected error\", \"schema\": { \"$ref\": \"#/definitions/Error\" } } } }, \"post\": { \"summary\": \"Create a pet\", \"operationId\": \"createPets\", \"tags\": [ \"pets\" ], \"responses\": { \"201\": { \"description\": \"Null response\" }, \"default\": { \"description\": \"unexpected error\", \"schema\": { \"$ref\": \"#/definitions/Error\" } } } } }, \"/pets/{petId}\": { \"get\": { \"summary\": \"Info for a specific pet\", \"operationId\": \"showPetById\", \"tags\": [ \"pets\" ], \"parameters\": [ { \"name\": \"petId\", \"in\": \"path\", \"required\": true, \"description\": \"The id of the pet to retrieve\", \"type\": \"string\" } ], \"responses\": { \"200\": { \"description\": \"Expected response to a valid request\", \"schema\": { \"$ref\": \"#/definitions/Pets\" } }, \"default\": { \"description\": \"unexpected error\", \"schema\": { \"$ref\": \"#/definitions/Error\" } } } } } }, \"definitions\": { \"Pet\": { \"required\": [ \"id\", \"name\" ], \"properties\": { \"id\": { \"type\": \"integer\", \"format\": \"int64\" }, \"name\": { \"type\": \"string\" }, \"tag\": { \"type\": \"string\" } } }, \"Pets\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Pet\" } }, \"Error\": { \"required\": [ \"code\", \"message\" ], \"properties\": { \"code\": { \"type\": \"integer\", \"format\": \"int32\" }, \"message\": { \"type\": \"string\" } } } } }" 
    }, 
    { 
     "id": "b4328bbc-bcb0-4313-b80c-a4394e553dd9", 
     "artifact": "{ \"swagger\": \"2.0\", \"info\": { \"title\": \"Uber API\", \"description\": \"Move your app forward with the Uber API\", \"version\": \"1.0.0\" }, \"host\": \"api.uber.com\", \"schemes\": [ \"https\" ], \"basePath\": \"/v1\", \"produces\": [ \"application/json\" ], \"paths\": { \"/products\": { \"get\": { \"summary\": \"Product Types\", \"description\": \"The Products endpoint returns information about the Uber products offered at a given location. The response includes the display name and other details about each product, and lists the products in the proper display order.\", \"parameters\": [ { \"name\": \"latitude\", \"in\": \"query\", \"description\": \"Latitude component of location.\", \"required\": true, \"type\": \"number\", \"format\": \"double\" }, { \"name\": \"longitude\", \"in\": \"query\", \"description\": \"Longitude component of location.\", \"required\": true, \"type\": \"number\", \"format\": \"double\" } ], \"tags\": [ \"Products\" ], \"responses\": { \"200\": { \"description\": \"An array of products\", \"schema\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Product\" } } }, \"default\": { \"description\": \"Unexpected error\", \"schema\": { \"$ref\": \"#/definitions/Error\" } } } } }, \"/estimates/price\": { \"get\": { \"summary\": \"Price Estimates\", \"description\": \"The Price Estimates endpoint returns an estimated price range for each product offered at a given location. The price estimate is provided as a formatted string with the full price range and the localized currency symbol.<br><br>The response also includes low and high estimates, and the [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code for situations requiring currency conversion. When surge is active for a particular product, its surge_multiplier will be greater than 1, but the price estimate already factors in this multiplier.\", \"parameters\": [ { \"name\": \"start_latitude\", \"in\": \"query\", \"description\": \"Latitude component of start location.\", \"required\": true, \"type\": \"number\", \"format\": \"double\" }, { \"name\": \"start_longitude\", \"in\": \"query\", \"description\": \"Longitude component of start location.\", \"required\": true, \"type\": \"number\", \"format\": \"double\" }, { \"name\": \"end_latitude\", \"in\": \"query\", \"description\": \"Latitude component of end location.\", \"required\": true, \"type\": \"number\", \"format\": \"double\" }, { \"name\": \"end_longitude\", \"in\": \"query\", \"description\": \"Longitude component of end location.\", \"required\": true, \"type\": \"number\", \"format\": \"double\" } ], \"tags\": [ \"Estimates\" ], \"responses\": { \"200\": { \"description\": \"An array of price estimates by product\", \"schema\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/PriceEstimate\" } } }, \"default\": { \"description\": \"Unexpected error\", \"schema\": { \"$ref\": \"#/definitions/Error\" } } } } }, \"/estimates/time\": { \"get\": { \"summary\": \"Time Estimates\", \"description\": \"The Time Estimates endpoint returns ETAs for all products offered at a given location, with the responses expressed as integers in seconds. We recommend that this endpoint be called every minute to provide the most accurate, up-to-date ETAs.\", \"parameters\": [ { \"name\": \"start_latitude\", \"in\": \"query\", \"description\": \"Latitude component of start location.\", \"required\": true, \"type\": \"number\", \"format\": \"double\" }, { \"name\": \"start_longitude\", \"in\": \"query\", \"description\": \"Longitude component of start location.\", \"required\": true, \"type\": \"number\", \"format\": \"double\" }, { \"name\": \"customer_uuid\", \"in\": \"query\", \"type\": \"string\", \"format\": \"uuid\", \"description\": \"Unique customer identifier to be used for experience customization.\" }, { \"name\": \"product_id\", \"in\": \"query\", \"type\": \"string\", \"description\": \"Unique identifier representing a specific product for a given latitude & longitude.\" } ], \"tags\": [ \"Estimates\" ], \"responses\": { \"200\": { \"description\": \"An array of products\", \"schema\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Product\" } } }, \"default\": { \"description\": \"Unexpected error\", \"schema\": { \"$ref\": \"#/definitions/Error\" } } } } }, \"/me\": { \"get\": { \"summary\": \"User Profile\", \"description\": \"The User Profile endpoint returns information about the Uber user that has authorized with the application.\", \"tags\": [ \"User\" ], \"responses\": { \"200\": { \"description\": \"Profile information for a user\", \"schema\": { \"$ref\": \"#/definitions/Profile\" } }, \"default\": { \"description\": \"Unexpected error\", \"schema\": { \"$ref\": \"#/definitions/Error\" } } } } }, \"/history\": { \"get\": { \"summary\": \"User Activity\", \"description\": \"The User Activity endpoint returns data about a user's lifetime activity with Uber. The response will include pickup locations and times, dropoff locations and times, the distance of past requests, and information about which products were requested.<br><br>The history array in the response will have a maximum length based on the limit parameter. The response value count may exceed limit, therefore subsequent API requests may be necessary.\", \"parameters\": [ { \"name\": \"offset\", \"in\": \"query\", \"type\": \"integer\", \"format\": \"int32\", \"description\": \"Offset the list of returned results by this amount. Default is zero.\" }, { \"name\": \"limit\", \"in\": \"query\", \"type\": \"integer\", \"format\": \"int32\", \"description\": \"Number of items to retrieve. Default is 5, maximum is 100.\" } ], \"tags\": [ \"User\" ], \"responses\": { \"200\": { \"description\": \"History information for the given user\", \"schema\": { \"$ref\": \"#/definitions/Activities\" } }, \"default\": { \"description\": \"Unexpected error\", \"schema\": { \"$ref\": \"#/definitions/Error\" } } } } } }, \"definitions\": { \"Product\": { \"properties\": { \"product_id\": { \"type\": \"string\", \"description\": \"Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles.\" }, \"description\": { \"type\": \"string\", \"description\": \"Description of product.\" }, \"display_name\": { \"type\": \"string\", \"description\": \"Display name of product.\" }, \"capacity\": { \"type\": \"string\", \"description\": \"Capacity of product. For example, 4 people.\" }, \"image\": { \"type\": \"string\", \"description\": \"Image URL representing the product.\" } } }, \"PriceEstimate\": { \"properties\": { \"product_id\": { \"type\": \"string\", \"description\": \"Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles\" }, \"currency_code\": { \"type\": \"string\", \"description\": \"[ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code.\" }, \"display_name\": { \"type\": \"string\", \"description\": \"Display name of product.\" }, \"estimate\": { \"type\": \"string\", \"description\": \"Formatted string of estimate in local currency of the start location. Estimate could be a range, a single number (flat rate) or \"Metered\" for TAXI.\" }, \"low_estimate\": { \"type\": \"number\", \"description\": \"Lower bound of the estimated price.\" }, \"high_estimate\": { \"type\": \"number\", \"description\": \"Upper bound of the estimated price.\" }, \"surge_multiplier\": { \"type\": \"number\", \"description\": \"Expected surge multiplier. Surge is active if surge_multiplier is greater than 1. Price estimate already factors in the surge multiplier.\" } } }, \"Profile\": { \"properties\": { \"first_name\": { \"type\": \"string\", \"description\": \"First name of the Uber user.\" }, \"last_name\": { \"type\": \"string\", \"description\": \"Last name of the Uber user.\" }, \"email\": { \"type\": \"string\", \"description\": \"Email address of the Uber user\" }, \"picture\": { \"type\": \"string\", \"description\": \"Image URL of the Uber user.\" }, \"promo_code\": { \"type\": \"string\", \"description\": \"Promo code of the Uber user.\" } } }, \"Activity\": { \"properties\": { \"uuid\": { \"type\": \"string\", \"description\": \"Unique identifier for the activity\" } } }, \"Activities\": { \"properties\": { \"offset\": { \"type\": \"integer\", \"format\": \"int32\", \"description\": \"Position in pagination.\" }, \"limit\": { \"type\": \"integer\", \"format\": \"int32\", \"description\": \"Number of items to retrieve (100 max).\" }, \"count\": { \"type\": \"integer\", \"format\": \"int32\", \"description\": \"Total number of items available.\" }, \"history\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Activity\" } } } }, \"Error\": { \"properties\": { \"code\": { \"type\": \"integer\", \"format\": \"int32\" }, \"message\": { \"type\": \"string\" }, \"fields\": { \"type\": \"string\" } } } } }" 
    } 
] 
} 

Действие:

export const RECEIVE_CATEGORY = 'RECEIVE_CATEGORY'; 
function receiveCategory(category) { 
    return { 
     type: RECEIVE_CATEGORY, 
     category 
    } 
} 

export function fetchCategory(categoryID) { 
    return function(dispatch) { 
     dispatch(requestCategory(categoryID)) 

     return fetch(`${baseURL}/categories/${categoryID}`, { 
      method: 'GET', 
      headers: { 
       'Accept' : 'application/json' 
      } 
     }) 
      .then(response => response.json()) 
      .then(json => dispatch(receiveCategory(json))) 
      .catch(function(error) { 
       console.log(error); 
      }); 
    } 
} 

Редуктор: категории функций (состояние = [], действие) {

switch(action.type) { 
      case RECEIVE_CATEGORIES : 
      return action.categories; 
     case RECEIVE_CATEGORY : 

      /* TODO : there has to be an easier way ...*/ 
      var index = 0; 
      for(index; index < state.length; index++) { 
       if(action.category.id === state[index].id) { 
        break; 
       } 
      } 

      var array= [...state.slice(0, index), 
       action.category, 
       ...state.slice(index+1) 
      ]; 
      return array; 
     default: 
      return state; 
    } 
} 
+0

Разве вы не можете просто заменить двойные кавычки с одинарные кавычки? 'str = str.replace (/ '/ g,"' ");' –

+0

Это действительно недействительный JSON. Обратные косые черты должны быть удвоены в строковой литературе, чтобы они имели смысл. Откуда вы берете эту строку? – trincot

+0

В частности, я получил его отсюда: https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/uber.json – ZeusSelerim

ответ

0

Вам нужно удвоить пробег обратной косой черты, представляя JSON в виде строки. Когда вы действительно извлекаете эти данные из службы или API, вы можете просто проанализировать ее, и она должна работать нормально. Посмотрите пример ниже.

var obj = { 
 
    "name": "This is some value \"escaped\"", 
 
    "artifact": "THE_JSON_STRING" 
 
}; 
 

 
var test = JSON.stringify(obj); 
 
console.log(test); 
 

 
var str = '{"name":"This is some value \\"escaped\\"","artifact":"THE_JSON_STRING"}'; 
 
console.log(test); 
 
console.log(test === str); 
 

 
try { 
 
    console.log(JSON.parse(str).name); 
 
} catch (error) { 
 
    console.log(error); 
 
}

+0

Я собираюсь принять этот ответ, но особая благодарность @ brso05 и trincot. Я действительно хотел решить эту клиентскую сторону, но в итоге я решил добавить парсер логической логики для исправления. Мне также удалось заставить его работать, если у него было 3 обратной косой черты. Для чего стоит его логика на стороне сервера: presentation.setArtifact (service.getArtifact(). Replace ("\\", "\\\\\\")); – ZeusSelerim