【发布时间】:2015-11-23 03:50:18
【问题描述】:
更新
您好,我目前在尝试连接到 Insightlys CRM 的 API 时遇到了 CORS 错误。我正在通过 POSTMAN 成功检索我的 Insightly CRM 数据。
Insightly 不支持 AJAX 请求的 CORS (http://support.insight.ly/hc/en-us/community/posts/206961417-Using-the-API-with-AJAX),您必须设置 API 代理脚本。我使用了以下提供的在 python 中完成的代理脚本并上传到我的专用主机。但我仍然收到 401 错误?
我对 API 代理很陌生,所以不确定我是否在这里遗漏了什么?
获取 https://api.insight.ly/v2.2/Contacts 401(未经授权)
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 调用:
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();
非常感谢您的帮助。
【问题讨论】:
-
他们的内容类型是否支持 JSONP(带填充的 Json)?您需要将响应视为 javascript。这通常可以解决 CORS 问题。
-
您好,感谢您的回复。我无法在他们的文档 ref jsonp 中找到任何内容。但是我确实尝试将 dataType 设置为 jsonp 并收到 GET 401 错误消息?
标签: jquery python ajax cors crm