2015-03-08 2 views
3

Я делаю вызов AJAX для CFC, чтобы вернуть одну запись из моей базы данных. Запись всегда возвращается как строка. Затем я обновляю поле ввода с этим значением.Возврат данных запроса CFC из вызова AJAX

Проблема заключается в том, что мое поле заселяется со следующим:

<wddxPacket version='1.0'><header/><data><string>0</string></data</wddxPacket> 

Вместо этого я хочу только значение строки. В этом примере: 0

AJAX вызова:

<script> 
function populateSalesTax(){ 
    // Populate the start and stop odometer text boxes 
    // when the selectlist ajax completes successfully 

     $.ajax({ 
      url:'cfcs/taxdata.cfc?method=getSalesTax', 
      data: { company_name: $("##company_name>option:selected").attr("Value") }, 
      success: function(response) { 
       console.log('Sales Tax Fubction Ran Successfully'); 
       $("##taxRate").val(response); 

       }, 
      error: function(response) { 
       console.log('Error' + response)} 
      }); 
    } 
</script> 

CFC Функция:

<cffunction name="getSalesTax" access="remote" returnType="string"> 
    <cfargument name="company_name" type="any" required="true"> 

    <!--- localize function variables ---> 
    <cfset var taxDetail = ""> 
    <cfoutput> 
    <cfquery name="taxDetail" datasource="#datasource#"> 
     SELECT tax_rate 
     FROM customer_table 
     <!--- adjust cfsqltype if needed ---> 
     WHERE company_name = <cfqueryparam value="#ARGUMENTS.company_name#" 
           cfsqltype="cf_sql_varchar"> 
    </cfquery> 
    </cfoutput> 

    <cfreturn taxDetail.tax_rate> 
</cffunction> 

Поле ввода:

<cfinput name="taxRate" id="taxRate" type="text" size="2" readonly="yes"> 
+3

В вашем вызове AJAX попробуйте 'cfcs/taxdata.cfc? Method = getSalesTax & ReturnFormat = json' – Chester

+0

Это сработало. Благодарю. –

+0

Легкий способ - не использовать ajax вообще. Запустите функцию в вашем файле .cfm и используйте атрибут value вашего тега cfinput. Не связано с вашим вопросом, но вам не нужен тег cfoutput в вашей функции. cfquery имеет один встроенный. –

ответ

1

У меня здесь много кода, потому что я делаю многое другое, но это эволюция. Вот как создать типичную таблицу:

if exists (select * from sysobjects where id = object_id(N'myTable') and OBJECTPROPERTY(id, N'IsUserTable') = 1) 
DROP TABLE myTable 
GO 
CREATE TABLE myTable(
myTableID Int Identity(1000,1) PRIMARY KEY NONCLUSTERED 
,myTableName varchar(128) default '' 
,myTableDesc varchar(max) default '' 
,myTableSort Int default 0 
) 
GO 
INSERT INTO myTable(myTableName,myTableSort) VALUES('One',1) 
INSERT INTO myTable(myTableName,myTableSort) VALUES('Two',2) 
INSERT INTO myTable(myTableName,myTableSort) VALUES('Three',3) 

Я использую хранимые процедуры. Вот код SQL:

create schema myTable authorization dbo 
-- It might seem odd to create a schema called with the name of the table, but that's how I organize the stored procedures by table name. 
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'myTable.[get]') AND type in (N'P', N'PC')) 
DROP PROC myTable.[get] 
GO 
CREATE PROC myTable.[get] 
(@UsrID Int 
,@RemoteAddr Varchar(15) 
,@myTableID Int 
) AS 
SELECT myTableID,myTableName,myTableDesc,myTableSort 
FROM myTable 
WHERE myTableID = @myTableID 
GO 
exec myTable.[get] 0,'',1001 

@UsrID - это первый параметр в каждой хранимой процедуре. Это кто хочет знать.

@RemoteAddr - второй параметр в каждой хранимой процедуре. Это IP-адрес пользователя. Теперь я знаю, что это не безупречно, но думаю, что безопасность такова, что 1) @UsrID - это то, что они знают (они должны были знать пароль, чтобы войти в систему как пользователь).

2) @RemoteAddr - это то, чем они владеют (хотя IP-адреса могут быть подделаны).

@myTableID является основным ключом для @myTable. Я всегда называю первичный ключ именем таблицы, за которым следует идентификатор.

Вот типичная .cfm страница:

<cfscript> 

</cfscript> 

<cfoutput> 
<cfinclude template="/Inc/html.cfm"> 
<link rel="stylesheet" type="text/css" href="Index.css"> 
<cfinclude template="/Inc/body.cfm"> 
<ul> 
    <li><a class="myClass" data-mytableid="1000" href="JavaScript:;">Click One!</a></li> 
    <li><a class="myClass" data-mytableid="1001" href="JavaScript:;">Click Two!</a></li> 
    <li><a class="myClass" data-mytableid="1002" href="JavaScript:;">Click Three!</a></li> 
</ul> 
<cfinclude template="/Inc/foot.cfm"> 
<script src="Index.js"></script> 
<cfinclude template="/Inc/End.cfm"> 
</cfoutput> 

Сценарий, который я включаю во всех моих страницах:

window.dom = {} 
dom.msg = $('#msg') 
dom.main = $('main') 
dom.fail = function(xhr, status, response) { 
    dom.msg.text(status + ': ' + response).addClass('label-warning') 
    dom.main.html(xhr.responseText) 
    debugger 
} 

и сценарий для самой страницы:

(function() { 
    $(document).on('click','.myClass',clicked) 

    function clicked() { 
     var local = {} 
     local.url = 'myTable.cfc' 
     local.type = 'POST' // or GET 
     local.dataType = 'json' 
     local.data = {} 
     local.data.method = 'get'; 
     local.data.myTableID = $(this).data('mytableid') 
     local.context = this; 
     result = $.ajax(local) 
     result.fail(dom.fail) 
     result.done(done) 
    } 
    function done(response, status, xhr) { 
//  console.log(response.COLUMNS) 
//  console.log(response.DATA) 
//  console.log(response.DATA[0]) 
//  console.log(response.DATA[0][0]) // myTableID 
//  console.log(response.DATA[0][1]) // myTableName 
//  console.log(response.DATA[0][2]) // myTableDesc 
//  console.log(response.DATA[0][3]) // myTableSort 
//  console.log(status) 
//  console.log(xhr) 
    } 
})() 

Наконец, myTable.cfc:

component { 

remote function get(myTableID) returnformat='json' { 
    storedproc dataSource=session.dataSource 
     procedure='myTable.[get]' { 
     procparam cfSqlType='cf_sql_integer' value=session.Usr.UsrID; 
     procparam cfSqlType='cf_sql_varchar' value=session.RemoteAddr; 
     procparam cfSqlType='cf_sql_integer' value=arguments.myTableID; 
     procresult resultset=1 name='result'; 
    } 
    return result 
} 
} 

И я должен вставить сокращенное приложение.CFC:

component { 
this.Name = 'myAJAX' 
this.dataSource = 'LR2015Summer1' 
this.SessionManagement = true 

function onSessionStart() { 
    session.dataSource = this.dataSource 
    session.RemoteAddr = getPageContext().getRequest().getRemoteAddr() 
    session.Usr = {} 
    session.Usr.UsrID = 0 
} 

function onRequestStart(LogCFCName) { 
    setting showDebugOutput=false; 
    if (isDefined('url.onSessionStart')) { 
     onSessionStart() 
    } 
    request.msg = '' 
    request.mod = 'label-info' 

    request.title='How I AJAX and return a query' 
    request.home = '/HowIWrite/AJAX/cfc' 
    request.css  = url.css  ?: true 
    request.js  = url.js  ?: true 
    request.bootstrap = url.bootstrap ?: true 
    request.bootstrap_theme = 'bootstrap-theme' 
    request.tryCatch = url.tryCatch ?: false 
    request.navbar = url.navbar ?: true 
    request.container = url.container ?: true 
    request.GoogleMaterialdesign = url.GoogleMaterialdesign ?: true 
    request.jQueryUI = url.jQueryUI ?: false 
    request.jQueryUI_theme = 'ui-lightness' // black-tie,blitzer,cupertino,dark-hive,dot-luv,eggplant,excite-bike,flick,hot-sneaks,humanity,le-frog,mint-choc,overcast,pepper-grinder,redmond,smoothness,south-street,start,sunny,swanky-purse,trontastic,ui-darkness,ui-lightness,vader 

    request.cgiName = getPageContext().getRequest().getServletPath() 
    request.cgiName = Left(request.cgiName,Len(request.cgiName)-4) 
    request.cgiName = ListLast(request.cgiName,'/') 
    request.cssName = request.cgiName & '.css' 
    request.jsName = request.cgiName & '.js' 
} 

} 
1

Вы можете изменить свой CFC как таковой:

<cfset response = { taxRate = taxDetail.tax_rate } /> 
<cfreturn serializeJSON(response)> 

(Аякса метод успех должен иметь response.TAXRATE)

или ваш Ajax вызова URL, как, например:

cfcs/taxdata.cfc?method=getSalesTax&ReturnFormat=json

Но

Судя по вам относительный путь в запросе Ajax url:'cfcs/taxdata.cfc?method=getSalesTax' я могу с уверенностью предположить, что вы пытаетесь сделать запрос Ajax на том же происхождения (тот же сайт) и вы на самом деле не необходимо a remote способ, но a public или package способ.

Вы должны знать о головных болях безопасности, которые приходят с объявлением метода remote. Без надлежащего уровня безопасности или role определено, что вы открыли метод для кого-либо, в том числе для злонамеренных пользователей.

Так, что вы должны иметь это:

  • другой уровень абстракции перед вашим CFC - на минимум только кубометра в минуту, что конкретизирует объект и вызывает getSalesTax, но в идеале рамки
  • доступ от public или package вместо remote
  • Соответствующий тип содержимого, объявленный на уровне абстракции, который возвращает объект ответа налоговой ставки (например, <cfcontent type="application/json" reset="true" />)
+0

Я не делал много вызовов ajax, и совсем недавно, но у меня смутные воспоминания о проблемах, если метод не удален. –

+0

запрос ajax точно так же, как и любой другой запрос, кроме асинхронного * или вне очереди. В современных браузерах запрос ajax не позволяет выполнить вызов сценария в другом домене (происхождении), чем текущий домен, если только он не предоставлен по-разному в заголовке доступа-источника (смотрите CORS). Это реализовано по соображениям безопасности в отношении межсайтового скриптинга, скомпрометированных веб-приложений и т. Д. * В этом случае * Я не говорю, что это проблема, но я предлагаю, чтобы он закрыл потенциальную дыру в своем приложении, и это удаленный метод – dwkd

+0

Я начал использовать слой, между которым поступают данные и где используются данные. Назовите это AppApi или что-то подобное.AppApi имеет экземпляр класса (возможно, AppObj), поэтому AppApi имеет удаленные методы для вызова общедоступных методов на AppObj. Основное преимущество, которое я вижу в этом, заключается в том, что объект AppObj постоянно присутствует в AppApi, но я думаю, что методы в AppApi, что вызовы страниц должны быть удалены, а не публичными или пакетными. Я смущен тем, что вы говорите? – Mike

Смежные вопросы