Facebook注册插件在登录FB后返回'invalid client_id',其中包含长/许多自定义字段



我正在使用FB注册插件,代码如下:

<html xmlns:fb="http://ogp.me/ns/fb#">
<script type="text/javascript">
window.fbAsyncInit = function() { FB.init({appId: 'xxx', status: true, cookie: true, xfbml: true}); };
(function() {
var e = document.createElement('script');
e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
})();
</script>

这是我想要的字段列表:

<?php /* There seems to be a character limit for fields causing "invalid client_id" on log in/out */?>
<fb:registration redirect-uri="https://xxx.secure.xxx.com/register/fb_submit.php"
fields='[
{"name":"name","view":"prefilled"},
{"name":"email"},
{"name":"password"},
{"name":"s_question","description":"Secret Question","type":"select","options":{"2":"In which city were you born?","4":"What is your favorite book?","3":"What is your favorite pets name?","6":"What is your favorite vacation spot?","1":"What is your mothers maiden name?"}},
{"name":"s_answer","type":"text","description":"Secret Answer"},
{"name":"first_name"},
{"name":"last_name"},
{"name":"address_co","description":"Care of (Optional)","type":"text","no_submit":true},
{"name":"address","description":"Mailing Address","type":"text"},
{"name":"address2","description":"Apartment/Unit","type":"text","no_submit":true},
{"name":"street_address","description":"Street Address (if using a P.O. box above)","type":"text","no_submit":true},
{"name":"location","view":"prefilled"},
{"name":"city","view":"not_prefilled","description":"City","type":"text"},
{"name":"state","view":"not_prefilled", "description":"State","type":"select","options":{"AA":"AA - Armed Forces Americas","AE":"AE - Armed Forces","AK":"AK - Alaska","AL":"AL - Alabama","AP":"AP - Armed Forces Pacific","AR":"AR - Arkansas","AS":"AS - American Samoa","AZ":"AZ - Arizona","CA":"CA - California","CO":"CO - Colorado","CT":"CT - Connecticut","DC":"DC - District of Columbia","DE":"DE - Delaware","FL":"FL - Florida","FM":"FM - Federated States of Micronesia","GA":"GA - Georgia","GU":"GU - Guam","HI":"HI - Hawaii","IA":"IA - Iowa","ID":"ID - Idaho","IL":"IL - Illinois","IN":"IN - Indiana","KS":"KS - Kansas","KY":"KY - Kentucky","LA":"LA - Louisiana","MA":"MA - Massachusetts","MD":"MD - Maryland","ME":"ME - Maine","MH":"MH - Marshall Islands","MI":"MI - Michigan","MN":"MN - Minnesota","MO":"MO - Missouri","MP":"MP - Northern Mariana Islands","MS":"MS - Mississippi","MT":"MT - Montana","NC":"NC - North Carolina","ND":"ND - North Dakota","NE":"NE - Nebraska","NH":"NH - New Hampshire","NJ":"NJ - New Jersey","NM":"NM - New Mexico","NV":"NV - Nevada","NY":"NY - New York","OH":"OH - Ohio","OK":"OK - Oklahoma","OR":"OR - Oregon","PA":"PA - Pennsylvania","PR":"PR - Puerto Rico","PW":"PW - Palau","RI":"RI - Rhode Island","SC":"SC - South Carolina","SD":"SD - South Dakota","TN":"TN - Tennessee","TX":"TX - Texas","UT":"UT - Utah","VA":"VA - Virginia","VI":"VI - Virgin Islands","VT":"VT - Vermont","WA":"WA - Washington","WI":"WI - Wisconsin","WV":"WV - West Virginia","WY":"WY - Wyoming"}},
{"name":"zip","description":"5-digit Zip Code","type":"text"},
{"name":"phone","description":"Phone (800-555-1212)","type":"text"},
{"name":"referred_by","description":"Referred by-Email or site nickname (Optional)","type":"text","no_submit":true},
{"name":"cert_code","description":"Gift Certificate Code (Optional)","type":"text","no_submit":true},
{"name":"sel_hear_about","description":"How Did You Hear About Us?","type":"select","options":{"1":"Friend","2":"Newspaper","3":"Magazine","4":"Internet Search","5":"Internet Ad","6":"Website","8":"site2","9":"site3","10":"Other","11":"TV","12":"Radio"}},
{"name":"hear_about","description":"newspaper/blog/website/friend name? (Optional) ","type":"text","no_submit":true},
{"name":"birthday"},
{"name":"hours","description":"Hours Spent Reading per Week (Optional)","type":"select","options":{"0":"0","1-5":"1-5","6-10":"6-10","11-20":"11-20","21-30":"21-30","31-40":"31-40","41+":"41+"},"no_submit":true}
]' onvalidate="validate">
</fb:registration>

这是我的validate()函数:

function validate(form)
{
errors = {};
var dt = new Date(), expiryTime = dt.setTime( dt.getTime() + 1000*5 );
var expires = dt.toGMTString();
if (form.first_name == "")
{
errors.first_name = "Please choose a First Name";
}
if (form.s_question == "-1")
{
errors.s_question = "Please choose a Secret Question";
}
if (form.s_answer == "")
{
errors.s_answer = "Please type an answer to your Secret Question";
}
if (form.address_co !== "")
{
set_cookie( 'address_co', form.address_co, expires, '/register', 'secure.xxx.com', true );
}
if (form.address == "")
{
errors.address = "Please type your mailing address";
}
if (form.address2 !== "")
{
set_cookie( 'address2', form.address2, expires, '/register', 'secure.xxx.com', true );
}
if (form.street_address !== "")
{
set_cookie( 'street_address', form.street_address, expires, '/register', 'secure.xxx.com', true );
}
if (form.zip == "")
{
errors.zip = "Please type a 5-digit Zip Code"
}
else if (form.zip.length != 5)
{
errors.zip = "Zip Code must be 5 digits";
}
else if (isNaN(form.zip))
{
errors.zip = "Zip Code must be a number";
}

if (form.phone == "")
{
errors.phone = "Please type your phone number";
}
if (form.referred_by !== "")
{
set_cookie( 'referred_by', form.referred_by, expires, '/register', 'secure.xxx.com', true );
}
if (form.cert_code !== "")
{
set_cookie( 'cert_code', form.cert_code, expires, '/register', 'secure.xxx.com', true );
}
if (!form.sel_hear_about)
{
errors.sel_hear_about = "Please choose how you heard about us";
}
if (form.hear_about !== "")
{
set_cookie( 'hear_about', form.hear_about, expires, '/register', 'secure.xxx.com', true );
}
if (form.hours !== "-1")
{
set_cookie( 'hours', form.hours, expires, '/register', 'secure.xxx.com', true );
}
return errors;
}

如果用户在访问此注册表表单时已经登录FB,则会填充FB字段,并且表单正常工作但是,如果用户未登录FB并选择表单上的FB提示"登录以在下面的表单中预先填充您的配置文件信息。",然后向FB提供登录凭据,则该表单将消失,并由FB中相当常见的"client_id"错误替换。

如果用户随后刷新页面,则表示他/她已登录FB,并填充了正确的FB字段。

我已经验证了JSON字段列表。在测试过程中,我发现如果我将字段列表缩减为:

fields='[
{"name":"name","view":"prefilled"},
{"name":"email"},
{"name":"password"},
{"name":"s_question","description":"Secret Question","type":"select","options":{"2":"In which city were you born?","4":"What is your favorite book?","3":"What is your favorite pets name?","6":"What is your favorite vacation spot?","1":"What is your mothers maiden name?"}},
{"name":"s_answer","type":"text","description":"Secret Answer"},
{"name":"first_name"},
{"name":"last_name"},                                                               ]' onvalidate="validate">

然后我没有得到错误。如果我重新添加最长的字段(上面的state字段),则返回client_id错误。我可以添加其他较短字段的组合,而不是添加state,从而得到相同的错误。这让我觉得我达到了JSON字段列表的某种最大大小限制。可能不是发送给FB的实际JSON,而是FB登录后返回的相应隐藏字段。

如果我无法解决这个问题,我计划只获取基本的FB字段,并将其余字段移到另一个页面。当然,我更喜欢把它放在一块,因为表单和我支持的注册代码都是在FB数据加载到表单中(刷新时)后工作的。

感谢您耐心等待这篇冗长的描述。

我对此没有任何解决方案,我只能提供一个可能的(不,我实际上认为是最有可能的)解释:

与所有其他插件一样,<fb:registration>标记所做的基本上是在页面中创建一个iframe,该iframe获取在查询字符串中作为GET参数传递的所有必要参数。

因此,您为注册表单定义的许多字段意味着iframe的URL中有一个长查询字符串。

问题是,浏览器限制了URL的可能长度——请参阅https://stackoverflow.com/a/417184/1427878,http://www.boutell.com/newfaq/misc/urllength.html

网络服务器也会这样做,然后他们说,"嗯,这对我来说有点太多了,通过GET处理,很抱歉,但没有对不起…">

因此,虽然您的注册表可能会在用户已经登录时使用许多定义的字段,因为iframe URL的长度处于浏览器或Facebook服务器强制执行的限制之下——如果用户登录并点击登录按钮,则会通过Facebook Auth流重定向,以及成功登录后他们应该"发送回"的URL(在这种情况下,注册表的地址及其所有GET参数)在Auth对话框URL中作为GET参数传输,以及其他参数。(当在另一个URL中作为GET参数传输URL时,需要应用必要的URL编码,这会让它更加糟糕…)

这导致了非常长的URL,在浏览器或Facebook服务器强制执行的限制下,该URL无法再传输/处理。(由于你收到了Facebook的错误消息,在这种情况下,Facebook的服务器很可能拒绝处理它。)

因此,你可以尝试用Facebook打开一个错误报告——他们设置最大GET URL长度的限制可以解决这个问题;但他们是否愿意这样做,这可能是另一个问题。(因为允许更长的请求URL可能还有其他含义。)

即使他们这样做了,你仍然可能会遇到用户使用的浏览器的障碍——如果Internet Explorer中的当前限制仍然是URL的路径部分2048个字符,那么这可能是下一个具有多个字段的注册表将在前端断开的部分…

最新更新