【问题标题】:Facebook graph api upload image withou sdkFacebook graph api上传图片没有sdk
【发布时间】:2014-01-08 19:30:46
【问题描述】:

有没有人尝试在没有 SDK 支持的情况下使用 FB graph api 上传图像?我正在尝试通过图形 api 资源管理器来做到这一点,我总是得到“需要上传文件”的响应。我正在使用 multipart/form-data 编码形成请求并使用“源”参数。一个有效的示例请求会很有帮助。

【问题讨论】:

  • 你用什么语言开发?
  • @madebydavid C++。虽然我想尝试使用图形 API 资源管理器或休息客户端的请求。
  • 我没有任何将 Graph API 与 C++ 结合使用的示例代码,抱歉。我在您的问题中添加了一个 C++ 标记。考虑在您的问题中添加更多内容,也许是一些代码,您可以在其中初始化要用于发出 HTTP 请求的库。没有 SDK 也可以做到这一点 - 我自己已经完成了,但是在 PHP 中使用 curl 库来执行 POST,而 SDK 似乎有点过头了。
  • 嗯..我一直在尝试通过图形 api explorer 形成多部分/表单数据编码的图像数据来发布(尝试了二进制图像数据和 base64 编码的二进制数据),我得到了 { #324} 不断。不幸的是,我在 fb 开发者文档中找不到相关信息。
  • 是的,这是行不通的 - Graph API Explorer 使用 AJAX 发出 POST 请求,而您不能使用 AJAX 发出多部分/表单数据请求。或者至少,Explorer 没有为我们提供一个界面,我们可以在其中破解这种功能。

标签: c++ facebook facebook-graph-api multipartform-data


【解决方案1】:

我用 openssl 编写了一个 c 示例代码。您可以关注在函数 iotask() 中实现的 http 原始数据部分。这是示例代码:

/*
  compile:
      gcc -o fb_photo_upload fb_photo_upload.c -lssl -lcrypto
*/

#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>

#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

/*
 * A image hex array. Let's say if you have a image file called 'myimage.png'.
 * then create the hex array as below:
 *     xxd -i myimage.png > myimage.c
 */
#include "myimage.c"

#define BOUNDARY "boundary12345"

char data_file_header[] = \
    "--" BOUNDARY "\r\n" \
    "Content-Disposition: form-data; name=\"source\"; filename=\"myimage.png\"\r\n" \
    "Content-Type: application/octet-stream\r\n\r\n";

char data_end[] = \
    "\r\n--" BOUNDARY "--\r\n";

int iotask(SSL *ssl) {
    int i, n, content_len;
    char *p;
    char writebuf[1024];
    char readbuf[1024];

    content_len = strlen(data_file_header) + myimage_png_len + strlen(data_end);

    p = writebuf;
    p += sprintf(p, "POST /v2.9/me/photos?access_token=EAAEcZAcqQqtUBAJyBItkYPLQ0URkZAFPwLXDbPZClSl3BgUvCjJk32Y5QvgNSDuuBMoC4VdoSOknQYJWnx7L2ZCZACPx5ZA2xfPd5ZB7gndtlIXoMkNumzIT0YKQkbqHgoJZBs3LWHw2UHZBbz3W9qm6xN4pKXzIAej1kunoBPGShDAABAB HTTP/1.1\r\n");
    p += sprintf(p, "Host: graph.facebook.com\r\n");
    p += sprintf(p, "Content-Type: multipart/form-data; boundary=" BOUNDARY "\r\n");
    p += sprintf(p, "Content-Length: %d\r\n", content_len);
    p += sprintf(p, "\r\n");
    SSL_write(ssl, writebuf, strlen(writebuf));

    SSL_write(ssl, data_file_header, strlen(data_file_header));
    SSL_write(ssl, myimage_png, myimage_png_len);

    SSL_write(ssl, data_end, strlen(data_end));

    n = SSL_read(ssl, readbuf, sizeof(readbuf));
    if (n > 0) {
        printf("read %d bytes\r\n", n);
        printf("++++++++ result ++++++++\r\n");
        printf("%s", readbuf);
        printf("-------- result --------\r\n");
    }
}

int create_socket(const char *hostname, const int port) {
    int sockfd;
    struct hostent *host;
    struct sockaddr_in dest_addr;

    if ( (host = gethostbyname(hostname)) == NULL ) {
        printf("cannot resolve hostname\r\n");
        abort();
    }

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    memset( &dest_addr, 0, sizeof(struct sockaddr_in) );
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(port);
    dest_addr.sin_addr.s_addr = *(long*)(host->h_addr);

    if ( connect(sockfd, (struct sockaddr *) &dest_addr, sizeof(struct sockaddr)) == -1 ) {
        printf("fail to connect\r\n");
    }

    return sockfd;
}

int main() {

    SSL_CTX *ctx;
    SSL *ssl;
    int sock = 0;

    const char *hostname = "graph.facebook.com";
    const int port = 443;

    OpenSSL_add_all_algorithms();
    ERR_load_BIO_strings();
    ERR_load_crypto_strings();
    SSL_load_error_strings();

    if( SSL_library_init() < 0 )
        printf("fail to init ssl\r\n");

    if ( (ctx = SSL_CTX_new(SSLv23_client_method())) == NULL )
        printf("fail to create ssl context\r\n");

    //Disable SSLv2 and enable all workarounds for buggy servers
    SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
    SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
    SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);

    ssl = SSL_new(ctx);

    if ( (sock = create_socket(hostname, 443)) < 0 )
        printf("fail to create socket\r\n");

    SSL_set_fd(ssl, sock);

    if ( SSL_connect(ssl) != 1 )
        printf("fail to build ssl session\r\n");

    iotask(ssl);

    SSL_free(ssl);
    close(sock);
    SSL_CTX_free(ctx);
    printf("end ssl connection\r\n");
    return(0);
}

【讨论】:

    猜你喜欢
    • 2013-04-19
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多