V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lydhr
V2EX  ›  jQuery

新手,已知某 web 服务的文档和 appid,应该如何调用 api

  •  
  •   lydhr · 2015-10-19 10:27:46 +08:00 · 3244 次点击
    这是一个创建于 3330 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 尝试用一些 http 请求的测试工具,如 Postman , uri 都测试成功,可以 post 到 json 数据。
    • 但是尝试用 jQuery ajax 的 getJson 方法实现跨越访问但是无法成功,回调函数的 error 也是空的。
    • 我是在 vs2013 的 aps.net 框架内写的 js ,然后在浏览器里面 run 测试,是不是必须要放在服务器上 run 才能拿到远程服务器的数据?
    • 但是随便写一个 js 就能调用到 flickr 的接口: http://api.flickr.com/services/feeds/photos_public.gne?tags=dog&tagmode=any&format=json&jsoncallback=?
    20 条回复    2015-10-22 13:20:28 +08:00
    qgy18
        1
    qgy18  
       2015-10-19 11:27:52 +08:00 via iPhone   ❤️ 1
    你需要弄明白「 Ajax ( XMLHttpRequest )」以及「 JSONP 」的原理,完全不是一回事。 CORS ( Cross Origin Resource Sharing )也可以了解下。

    最好自己用原生 JS 分别实现一下, JQ 帮你做了太多事。例如你举的最后那个 case , JQ 帮你把最后的 ? 替换为 callback name ,本质上还是加载并执行一个第三方外链 JS 文件,跟 XHR 没啥关系。
    lydhr
        2
    lydhr  
    OP
       2015-10-19 13:31:12 +08:00
    @qgy18 我使用一下方法是否有问题呢
    `$.ajax({ //底层方法;
    url: myUri,
    type: "POST",
    dataType: "json", //使用 JSONP 方法进行 AJAX,json 有跨域问题;
    success: function (data, status) {
    $("#hrdMsg").text("success");
    },
    error: function(obj,info,errObj){
    $("#hrdMsg").text("[obj]"+obj+"[info]"+info+"[errObj]"+errObj);
    }
    }); `
    lydhr
        3
    lydhr  
    OP
       2015-10-19 13:54:15 +08:00
    @qgy18 我用 chrome 调试可以看到, response header 里面的 content length 和 postman 中的相同,说明成功得到需要的 response ,但是$.ajax 仍然是 fail
    hcymk2
        4
    hcymk2  
       2015-10-19 14:18:17 +08:00
    fail 里面应该有 message 吧。还有 chrome 下 response 内容是什么?
    iyaozhen
        5
    iyaozhen  
       2015-10-19 14:52:26 +08:00
    @lydhr 你这里有错误。
    iyaozhen
        6
    iyaozhen  
       2015-10-19 15:03:50 +08:00
    打快了, jsonp 不支持 post 吧。
    qgy18
        7
    qgy18  
       2015-10-19 15:29:54 +08:00
    @lydhr 本来写了一大段又删掉了。建议楼主还是自己去弄明白原理,这样印象最深刻。

    简而言之,你要搞明白 XHR 和 JSONP 的本质区别,你要了解你这个请求真正用的是什么方式去发送的数据(在 Chrome 开发者工具 network Tab 下, XHR 请求会显示在 XHR 下, JSONP 请求会显示在 JS 下)。

    不要被 JQ 的 Ajax 给蒙蔽了。
    lydhr
        8
    lydhr  
    OP
       2015-10-19 15:51:34 +08:00
    @iyaozhen 注释与实际代码不符, datatype 是用的 json
    gamexg
        9
    gamexg  
       2015-10-19 15:52:34 +08:00   ❤️ 1
    浏览器有跨域保护,需要 post 的 api 无法使用(很难)。
    这个 api 需要你在你的 asp.net 服务器包装一下这个接口来使用,即:
    浏览器 js 调用你的服务器的 api
    你服务器 api 收到请求后在调用第三方,然后将第三方的响应返回给浏览器。
    lydhr
        10
    lydhr  
    OP
       2015-10-19 15:55:12 +08:00
    @hcymk2 我用 postman 测试是成功的, postman 的 response 和我的代码的 response 是一摸一样的,但是我的代码 fail 而且没有 message , console 里面报了 access-control-allow-origin 的错;
    lydhr
        11
    lydhr  
    OP
       2015-10-19 16:04:30 +08:00
    @qgy18 我用 postman 测试是成功的, postman 的 response 和我的代码的 request header 除了 origin 其他都是一样的
    matsuijurina
        12
    matsuijurina  
       2015-10-19 16:42:06 +08:00
    肯定还是跨域的问题,@gamexp 是正解。解决方法在服务器端,比如 golang 就需要加这几句
    w.Header().Set("Content-Type", "application/json;charset=UTF-8")
    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
    w.Header().Set("Access-Control-Allow-Headers",
    "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")

    Rails 好像改一行代码就可以了。
    qgy18
        13
    qgy18  
       2015-10-19 16:47:42 +08:00
    @lydhr postman 是用 Chrome 扩展发的请求,不受浏览器同源策略限制。

    XHR 你如果想要跨域也是可以的,服务端输出 CORS ( Cross Origin Resource Sharing )头就可以了。
    lydhr
        14
    lydhr  
    OP
       2015-10-19 17:43:47 +08:00
    @matsuijurina @gamexg
    感觉是跨越问题,服务器是学校的教务处的,只给了 appid 和文档供爱好编程的同学测试用,所以不能修改服务器端。
    ***
    仍然有两个疑问:
    - 出于安全学校应该没有 Set("Access-Control-Allow-Origin", "*") ,我在校外可能无法访问,但是为什么 postman 可以,看了一下 postman 的 origin 是: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
    - 像微信公众平台等这样的公共接口,是需要大家注册的时候填写自己服务器的 url 的,所以微信接下来做的就是在 Access-Control-Allow-Origin 里面加上我的 url ,我就可以访问了?
    lydhr
        15
    lydhr  
    OP
       2015-10-19 17:46:13 +08:00
    @qgy18 postman 的和我的 request 都是 XHR 的,但是 postman 可以 while 我不可以
    hcymk2
        16
    hcymk2  
       2015-10-19 17:52:28 +08:00
    matsuijurina
        17
    matsuijurina  
       2015-10-19 18:15:11 +08:00   ❤️ 1
    @lydhr 前面很多回复已经讲得很清楚了。不管是你的网页里跑的 JS ,还是 Postman ,它们发的请求远程服务器都收到了,也正常返回了。但是由于浏览器的同源安全策略,在浏览器里运行的 JS 没有权限去访问返回的内容。而 Postman 是一个 Chrome 的 Extension ,虽然它本质上也是用 html 、 css 、 javascript 写出来的,但是 Chrome 给予了它更多的权限,比如 Cross-Origin XMLHttpRequest ,可以解决跨域的问题,具体可参见官方文档 https://developer.chrome.com/extensions/xhr

    那么,在不能修改远程服务器返回内容的情况下,如何解决你面临的问题呢? @gamexg 已经说了,你需要一个过桥的服务器,比如你用的是 asp.net ,网页上的 JS 不管是 GET 还是 POST 请求都直接发到本地同源的服务器,再由本地服务器向远程服务器提交请求,这时就不再有跨域的问题了。
    qgy18
        18
    qgy18  
       2015-10-19 19:27:41 +08:00
    @lydhr 前面说过了这是浏览器同源策略,扩展在安装的时候就声明过要访问哪些 URL ,你同意了所以没问题。

    要想发送跨域 XHR ,除了前面说过的 CORS ,其实你还可以 disable Chrome 的同源策略,因为只作用于你自己的 Chrome ,所以仅供调试,具体做法:

    Mac : open -a /Applications/Google\ Chrome.app --args --disable-web-security
    Win : start chrome.exe --args --disable-web-security

    上张截图:

    codeyung
        19
    codeyung  
       2015-10-19 19:39:04 +08:00
    json != jsonp
    lydhr
        20
    lydhr  
    OP
       2015-10-22 13:20:28 +08:00
    @matsuijurina Best answer. Many thx!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2555 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 70ms · UTC 04:42 · PVG 12:42 · LAX 20:42 · JFK 23:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.