Как кодировать символ & для пакетных запросов? - PullRequest
3 голосов
/ 22 сентября 2011

У меня есть пакетный запрос Facebook , который выглядит следующим образом:

https://graph.facebook.com/?access_token=ACCESS_TOKEN&batch=[{"method": "GET", "lative_url ":" search?q=EMAIL@ADDRESS.COM&type=user "}]

Отправка по проводу:

{"error"=>0, "error_description"=>"batch parameter must be a JSON array"} 

Если я удаляю &type=user, он работает нормально (отправляет обратно пустой массив данных). Я абсолютно уверен, что Facebook неправильно анализирует символ &. Я где-то читал в Интернете, что я мог бы попытаться кодировать символ & в% 26, однако вместо этого, похоже, вместо этого выполняется запрос "EMAIL@ADDRESS.COM%26type=user". Если вы измените порядок параметров, вы поймете, что я имею в виду.

Есть какие-нибудь идеи, как заставить парсер пакетных запросов распознавать символ &, не отправляя сообщение об ошибке, которое никогда не будет исправлено?

EDIT:

Я использую URI.encode. Вот точный код:

    queries = email_array.map { |email| { :method => "GET", :relative_url => "search?q=#{email}&type=user" } }
    route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
    res = HTTParty.post(route)

Ответы [ 3 ]

3 голосов
/ 22 сентября 2011

После того, как я немного поигрался с этим, мне удалось воспроизвести то же поведение, даже с тщательной проверкой и двойной проверкой того, что я правильно следовал спецификациям API. Это похоже на ошибку в пакетном методе Facebook - он неправильно понимает амперсанды в значениях параметров.

2 голосов
/ 22 сентября 2011

Не используйте строковый литерал для создания json. Используйте to_json, как показано ниже. (Кроме того, не используйте обозначения {} для более чем одной строки, используйте do / end).

queries = []
email_array.each do |email|
  queries << {:method => 'GET', :relative_url => "search?q=#{email}&type=user"}
end

route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
res = HTTParty.post(route)

Кроме того, вы можете использовать Array#map для простого кода, например:

queries = email_array.map { |email| {:method => 'GET', :relative_url => "search?q=#{email}&type=user"} }
route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
res = HTTParty.post(route)

РЕДАКТИРОВАТЬ: ниже приведен мой оригинальный ответ до редактирования вопроса, для справки.

Попробуйте правильно URL кодировать весь параметр:

https://graph.facebook.com/?access_token=ACCESS_TOKEN&batch=[%7B%22method%22:%20%22GET%22,%20%22relative_url%22:%20%22search?q=EMAIL@ADDRESS.COM&type=user%22%7D]

На практике вы будете использовать URI.encode из библиотеки uri, чтобы сделать это. Пример: * +1021 *

irb(main):001:0> require 'uri'
=> true
irb(main):002:0> URI.encode('[{"method": "GET", "relative_url": "search?q=EMAIL@ADDRESS.COM&type=user"}]')
=> "[%7B%22method%22:%20%22GET%22,%20%22relative_url%22:%20%22search?q=EMAIL@ADDRESS.COM&type=user%22%7D]"

Или, что еще лучше, используйте to_json, чтобы создать строку json. Пример:

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'json'
=> true
irb(main):003:0> require 'uri'
=> true
irb(main):004:0> URI.encode([{:method => 'GET', :relative_url => 'search?q=EMAIL@ADDRESS.COM&type=user'}].to_json)
=> "[%7B%22method%22:%22GET%22,%22relative_url%22:%22search?q=EMAIL@ADDRESS.COM&type=user%22%7D]"
0 голосов
/ 13 апреля 2015

Если это кому-нибудь поможет, когда мое пакетное обновление AdSet не удалось из-за того, что в одном из названий интересов был символ "&":

{u'id': u'6003531450398', u'name': u'Dolce & Gabbana'}

Я узнал, что имя может быть любым, и пока идентификатор правильный, FB будет заполнять само имя.

...