weixin_33724659 2015-11-23 03:50 采纳率: 0%
浏览 38

Insightly CRM Ajax API代理

UPDATE

Hi I am currently having getting an error with CORS when trying to connect to Insightlys CRM's API. I am successfully retrieving my Insightly CRM data through POSTMAN.

Insightly does not support CORS for AJAX requests (http://support.insight.ly/hc/en-us/community/posts/206961417-Using-the-API-with-AJAX) and you have to setup an API proxy script. I have used the below supplied proxy script done in python and uploaded to my dedicated hosting. But I am still getting a 401 error?

I am quite new to API proxies so not sure if I am missing something here?

GET https://api.insight.ly/v2.2/Contacts 401 (Unauthorized)

apiproxy.py

#
# Insightly API Proxy for Python / App Engine
# Brian McConnell <brian@insightly.com>
#
# This utility is designed to act as an API proxy server. It is written in  Python 2.7
# and will run without modification on Google App Engine. Just serve your JavaScript
# from the /js directory in this project, and AJAX requests should be relayed through
# to the Insightly service. This should also run on any webapp2 compatible server platform
#

import base64
import os
import string
import types
import urllib
import urllib2
import webapp2
import wsgiref.handlers

#
# import google app engine libraries, replace these with standard 
#

try:
    from google.appengine.ext import webapp
except:
# skip Google App Engine webapp library
    pass

base_url = 'https://api.insight.ly/v2.2'

def authenticate():
#
# add user validation logic here, be careful to do this in a way that does not expose user secrets such as
# the user API key (this is why we do not allow CORS in the first place)
#

# hardcoding API key for now

apikey = 'fillinhere'
return base64.encode(apikey)

def generateRequest(url, method, data, alt_auth=None, test=False, headers=None):
"""
This method is used by other helper functions to generate HTTPS requests and parse server responses. This will minimize the amount of work developers need to do to integrate with the Insightly API, and will also eliminate common sources of errors such as authentication issues and malformed requests. Uses the urllib2 standard library, so it is not dependent on third party libraries like Requests
"""
if type(url) is not str: raise Exception('url must be a string')
if type(method) is not str: raise Exception('method must be a string')
valid_method = False
response = None
text = ''
if method == 'GET' or method == 'PUT' or method == 'DELETE' or method == 'POST':
valid_method = True
else:
raise Exception('parameter method must be GET|DELETE|PUT|UPDATE')
request = urllib2.Request(url)
request.get_method = lambda: method
request.add_header('Content-Type', 'application/json')
if headers is not None:
headerkeys = headers.keys()
for h in headerkeys:
    request.add_header(h, headers[h])
# open the URL, if an error code is returned it should raise an exception
if method == 'PUT' or method == 'POST':
result = urllib2.urlopen(request, data)
else:
result = urllib2.urlopen(request)
text = result.read()
return text

class APIProxyHandler(webapp2.RequestHandler):

def delete(self):
    apikey = authenticate()
    path_qs = self.request.headers['path_qs']
    url = base_url + path_qs
    headers = {'Authorization','Basic ' + api_key}
    text = generateRequest(url, 'DELETE', None, headers=headers)
    self.response.headers['Content-Type']='application/json'
    self.response.out.write(text)
def get(self):
    apikey = authenticate()
    path_qs = self.request.headers['path_qs']
    url = base_url + path_qs
    headers = {'Authorization','Basic ' + api_key}
    text = generateRequest(url, 'GET', None, headers=headers)
    self.response.headers['Content-Type']='application/json'
    self.response.out.write(text)
def post(self):
    body = self.request.headers['body']
    path_qs = self.request.headers['path_qs']
    url = base_url + path_qs
    headers = {'Authorization','Basic ' + api_key}
    text = generateRequest(url, 'POST', body, headers=headers)
    self.response.headers['Content-Type']='application/json'
    self.response.out.write(text)
def put(self):
    body = self.request.headers['body']
    path_qs = self.request.headers['path_qs']
    url = base_url + path_qs
    headers = {'Authorization','Basic ' + api_key}
    text = generateRequest(url, 'PUT', body, headers=headers)
    self.response.headers['Content-Type']='application/json'
    self.response.out.write(text)

app = webapp2.WSGIApplication([("r/(.*)", APIProxyHandler)], debug=True)
# map generic page server request handler

jQuery/Ajax call:

Insightly = function () {
var _t = this;

this.events = function () {
    $(".contactsform").submit(_t.searchContacts);
};
this.searchContacts = function (event) {
event.preventDefault();
var $search = $(this);
console.log('[ Search contacts event ]');

$.ajaxPrefilter( function( options ) {
    if ( options.crossDomain ) {
    var newData = {};

    newData.data = $.extend({}, options.data);
    newData.url = options.url;

    options = {};

    // Set the proxy URL
    options.url = "http://www.blahblah.comm/apiproxy.py";
    console.log("ajaxprefilter");
    options.data = $.param(newData);
    console.log(options);
    options.crossDomain = false;
}
});
// How to use the cross domain proxy
$.ajax({         
    url: 'https://api.insight.ly/v2.2/Contacts',
    crossDomain: true, 
    processData: false 
    }).success(function(data) { 
    var jsonData = JSON.parse(data); 
    console.log(jsonData); 
});
};//End SearchContacts
this.init = function () {
    _t.events();
};
this.init();
return (this);   
};//End main function
var LZ = new Insightly();

Your help is greatly appreciated.

  • 写回答

1条回答 默认 最新

  • H_MZ 2015-11-23 05:27
    关注

    This means that you cannot access their API directly using AJAX or javascript http request from the client-side. What you need to do is create a "Proxy" API.

    A "Proxy" API is the service that you need to host in your own domain where the client code lies. You need to write an authenticated server-side API call to Insightly CRM API with your favorite server-side language and call this with your jquery AJAX.

    So the following code will be:

    var searchNotesUrl = "https://myowndomain.com/your/api/proxy/notes"
    

    In other words, your server-side script will be the one relaying the data from CRM API to your client.

    If it is still getting 401 response, then maybe you need to check the User and API Key credentials if they are correct.

    UPDATE

    You entirely changed the question now. My answer above was intended for the last question version that you had.

    For new answer, you have a problem with this code:

    $.ajaxPrefilter( function( options ) {
        if ( options.crossDomain ) {
        var newData = {};
    
        newData.data = $.extend({}, options.data);
        newData.url = options.url;
    
        options = {};
    
        // Set the proxy URL
        options.url = "http://www.blahblah.comm/apiproxy.py";
        console.log("ajaxprefilter");
        options.data = $.param(newData);
        console.log(options);
        options.crossDomain = false;
    }
    });
    // How to use the cross domain proxy
    $.ajax({         
        url: 'https://api.insight.ly/v2.2/Contacts',
        crossDomain: true, 
        processData: false 
        }).success(function(data) { 
        var jsonData = JSON.parse(data); 
        console.log(jsonData); 
    });
    

    First, you are still requesting to the 'https://api.insight.ly/v2.2/Contacts' . You do not need to request to this URL anymore as you already have the proxy api. The proxy api ("http://www.blahblah.comm/apiproxy.py") is the one that you should be directly calling instead of sending request to insight.ly.

    Your Proxy API, should handle all api request that can be sent in insight.ly. Which means that "http://www.blahblah.comm/apiproxy.py" can support notes , Contacts and etc.

    Second, as you can read the python script, it actually looks for a request header key 'path_qs' . The path_qs value should be something like /Contacts. The reason being is because path_qs is being concatenated with base_url = 'https://api.insight.ly/v2.2' inside the script thru url = base_url + path_qs.

    So the code would be like:

    $.ajax({ 
       method: 'GET', //this is because it is supposed to be GET
       crossDomain: true,
       dataType: 'json',
       url: 'http://www.blahblah.comm/apiproxy/that/executes', 
       headers: { 'path_qs': '/Contacts' },
       success : function(data, status, xhr) {
          console.log(data);
       }
    });
    

    You need to setup the Python script in Google app engine cloud as an application. To learn more, this is entirely new topic: https://cloud.google.com/appengine/docs/python/gettingstartedpython27/helloworld

    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料