【问题标题】:How to solve flutter wordpress json api error?如何解决flutter wordpress json api错误?
【发布时间】:2019-02-10 02:00:43
【问题描述】:

我正在尝试从我的 wordpress 网站 http://crunchbox.epizy.com/wp-json/wp/v2/ 在一个颤振应用程序上解析 json,该应用程序从所有现有帖子中获取标题和特色图片,代码如下:

final String apiUrl = "http://crunchbox.epizy.com/wp-json/wp/v2/";
  List posts;

  Future<String> getPosts() async {
    var res = await http.get(apiUrl,
        headers: {"Accept": "application/json"});

    setState(() {
      var resBody = jsonDecode(res.body);
      print(resBody);
      posts = resBody;
    });
    return "Success!";

运行此代码后,我收到此错误:

E/flutter ( 2931): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter ( 2931): FormatException: Unexpected character (at character 1)
E/flutter ( 2931): <html><body><script type="text/javascript" src="/aes.js" ></script><script>...
E/flutter ( 2931): ^
E/flutter ( 2931): 
E/flutter ( 2931): #0      _ChunkedJsonParser.fail (dart:convert/runtime/libconvert_patch.dart:1362:5)
E/flutter ( 2931): #1      _ChunkedJsonParser.parseNumber (dart:convert/runtime/libconvert_patch.dart:1258:9)
E/flutter ( 2931): #2      _ChunkedJsonParser.parse (dart:convert/runtime/libconvert_patch.dart:926:22)
E/flutter ( 2931): #3      _parseJson (dart:convert/runtime/libconvert_patch.dart:29:10)
E/flutter ( 2931): #4      JsonDecoder.convert (dart:convert/json.dart:542:36)
E/flutter ( 2931): #5      JsonCodec.decode (dart:convert/json.dart:169:41)
E/flutter ( 2931): #6      jsonDecode (dart:convert/json.dart:101:10)
E/flutter ( 2931): #7      _WordpressHomeState.getPosts.<anonymous closure> (file:///C:/Users/Arbaaz_AJ/IdeaProjects/wordpress_flutter/lib/main.dart:31:21)
E/flutter ( 2931): #8      State.setState (package:flutter/src/widgets/framework.dart:1125:30)
E/flutter ( 2931): #9      _WordpressHomeState.getPosts (file:///C:/Users/Arbaaz_AJ/IdeaProjects/wordpress_flutter/lib/main.dart:30:5)
E/flutter ( 2931): <asynchronous suspension>
E/flutter ( 2931): #10     _WordpressHomeState.initState (file:///C:/Users/Arbaaz_AJ/IdeaProjects/wordpress_flutter/lib/main.dart:41:10)
E/flutter ( 2931): #11     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3751:58)
E/flutter ( 2931): #12     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5)
E/flutter ( 2931): #13     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
E/flutter ( 2931): #14     Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
E/flutter ( 2931): #15     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14)
E/flutter ( 2931): #16     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
E/flutter ( 2931): #17     Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
E/flutter ( 2931): #18     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
E/flutter ( 2931): #19     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
E/flutter ( 2931): #20     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3622:5)
E/flutter ( 2931): #21     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5)
E/flutter ( 2931): #22     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
E/flutter ( 2931): #23     Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
E/flutter ( 2931): #24     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14)
E/flutter ( 2931): #25     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
E/flutter ( 2931): #26     Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
E/flutter ( 2931): #27     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14)
E/flutter ( 2931): #28     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
E/flutter ( 2931): #29     Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
E/flutter ( 2931): #30     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14)
E/flutter ( 2931): #31     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
E/flutter ( 2931): #32     Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
E/flutter ( 2931): #33     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4654:14)
E/flutter ( 2931): #34     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
E/flutter ( 2931): #35     Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
E/flutter ( 2931): #36     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
E/flutter ( 2931): #37     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
E/flutter ( 2931): #38     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3622:5)
E/flutter ( 2931): #39     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3769:11)
E/flutter ( 2931): #40     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3617:5)
E/flutter ( 2931): #41     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2907:14)
E/flutter ( 2931): #42     Element.updateChild (package:flutter/src/widgets/framework.dart:2710:12)
E/flutter ( 2931): #43     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
E/flutter ( 2931): #44     Element.rebuild (package:flutter/src/widg

我想要实现的是在列表视图中获取标题和摘录 这是代码:

FadeInImage.memoryNetwork(
                        placeholder: kTransparentImage,
                        image: posts[index]["featured_media"] == 0
                            ? 'images/placeholder.png'
                            : posts[index]["_embedded"]["wp:featuredmedia"][0]
                                ["source_url"],
                      ),
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: ListTile(
                          title: Padding(
                            padding: EdgeInsets.symmetric(vertical: 10.0),
                            child: Text(posts[index]["title"]["rendered"]),
                          ),
                          subtitle: Text(posts[index]["excerpt"]["rendered"]
                              .replaceAll(new RegExp(r'<[^>]*>'), '')),
                        ),

请帮帮我,谢谢。

【问题讨论】:

  • 请求返回包含 JSON 的 HTML。 &lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;pre style="word-wrap: break-word; white-space: pre-wrap;"&gt;{"namespace":"wp\/v2","routes":{"\/wp\/v ...。我不知道是否有获取纯 JSON 的 API。可以使用pub.dartlang.org/packages/html提取JSON内容

标签: wordpress flutter wordpress-json-api


【解决方案1】:

您的 API 正在返回一个 html 响应,作为其机器人保护的一部分。响应实际上是一些代码,需要在服务器允许它访问 API 之前在您的客户端上运行。

这是它返回的 html(不是故意格式化的):

<html><body><script type="text/javascript" src="/aes.js" ></script><script>function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}function toHex(){for(var d=[],d=1==arguments.length&&arguments[0].constructor==Array?arguments[0]:arguments,e="",f=0;f<d.length;f++)e+=(16>d[f]?"0":"")+d[f].toString(16);return e.toLowerCase()}var a=toNumbers("..................."),b=toNumbers(".................."),c=toNumbers("...........");document.cookie="__test="+toHex(slowAES.decrypt(c,2,a,b))+"; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/"; location.href="http://crunchbox.epizy.com/wp-json/wp/v2/posts?i=1";</script><noscript>This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support</noscript></body></html>

重要的是中间的javascript:

function toNumbers(d) {
    var e = [];
    d.replace(/(..)/g, function(d) {
        e.push(parseInt(d, 16))
    });
    return e
}

function toHex() {
    for (var d = [], d = 1 == arguments.length && arguments[0].constructor == Array ? arguments[0] : arguments, e = "", f = 0; f < d.length; f++) e += (16 > d[f] ? "0" : "") + d[f].toString(16);
    return e.toLowerCase()
}
var a = toNumbers("..............."),
    b = toNumbers("..............."),
    c = toNumbers("...............");
document.cookie = "__test=" + toHex(slowAES.decrypt(c, 2, a, b)) + "; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/";
location.href = "http://crunchbox.epizy.com/wp-json/wp/v2/posts?i=1"; < /script>

请注意,我已经替换了toNumber("abcd1234") with....`中的三个二进制序列。

如果您有权访问为 wordpress 站点提供服务的 NGINX 服务器(我假设),则可以禁用此功能。或者您可以使用 wordpress 的身份验证并通过插件添加额外的身份验证方法 - 请参阅 wordpress documentation for api authentication 的底部。

第三个选项是您可以“运行” js 代码并使用标头将 cookie 设置到您的请求中。显然flutter无法原生运行js。但理论上你可以在 android 和 ios 上使用 webviews 来完成,或者你可以解析代码以找到“a”、“b”和“c”并使用某种库执行 AES-128 cbc 解密 (@987654322 @ 可能工作,但没有承诺)。

【讨论】:

  • 我如何禁用这个机器人保护,你能告诉我禁用这个的缺点是什么。
  • 缺点是您将服务器的 API 开放给机器人。这可能是一个问题,也可能不是问题,但它肯定至少意味着您的服务器提供的流量。而且由于您的网站似乎托管在免费服务上,因此它们可能有相当严格的限制。但是,如果您有权访问这些文件,禁用它应该不难。在 nginx 配置文件(/usr/local/nginx/conf、/etc/nginx 或 /usr/local/etc/nginx)中应该有一行类似于 testcookie on;.. 删除它并使用 /etc/init.d/nginx restart 重新启动
  • 我所说的另一个选项是添加一个 wordpress 插件进行身份验证(或使用基本身份验证,即用户名和密码)。然后,诀窍是确保您不将密码用于具有任何重要权限的帐户。您可以创建一个对您需要服务的所有内容具有只读访问权限的新用户,并将其用作您用于访问 API 的用户。这样做的缺点是您必须将该用户和密码嵌入到您的应用中,并且该应用的所有流量都会显示为该用户......尽管这实际上可能是一件好事。
  • The Application Password plugin 似乎是个不错的选择。这样,您就可以使用户具有只读权限(确保也禁用草稿页面访问),然后为其生成应用程序密码,然后在您的应用程序中将身份验证标头添加到您的 http 请求中。使用应用程序密码的好处是,即使有人从您的应用程序中提取了密码,我不相信他们能够登录 wordpress 网站,而只是使用它来访问 api。
  • 这已经离题了,所以我最好不要再继续下去了。如果您遇到问题,我建议您针对 wordpress/nginx 而不是颤振提出问题,因为这与颤振几乎没有关系(无论您尝试使用哪个客户端访问,都会遇到同样的问题wordpress API)
猜你喜欢
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
  • 2022-10-02
  • 2022-11-03
  • 2022-08-19
  • 1970-01-01
  • 2021-03-04
  • 2021-09-24
相关资源
最近更新 更多