programing

jQuery Ajax 호출 및 HTML.위조 방지토큰()

javamemo 2023. 3. 31. 21:20
반응형

jQuery Ajax 호출 및 HTML.위조 방지토큰()

인터넷상의 블로그 투고에서 읽은 정보에 따라 CSRF 공격의 완화를 앱에 실장했습니다.특히, 이 투고는, 제 도입의 원동력이 되고 있습니다.

기본적으로 CSRF 공격을 방지하기 위해서는 다음 코드를 구현해야 한다고 기술되어 있습니다.

  1. , 그럼 여기에다가 더해져요.[ValidateAntiForgeryToken] Http Http를

    [Http Post] [검증]위조 방지토큰] 퍼블릭액션 결과 SomeAction(SomeModel 모델) { }

  2. , 그럼 여기에다가 더해져요.<%= Html.AntiForgeryToken() %> to .는 helper inside forms.

어쨌든, 앱의 일부에서는, jQuery로 서버에 Ajax POST를 전혀 폼을 만들지 않고 실행하고 있습니다.예를 들어 사용자가 특정 작업을 수행하기 위해 이미지를 클릭할 수 있도록 하는 경우 등이 있습니다.

활동 목록이 있는 테이블이 있다고 가정해 봅시다.테이블의 컬럼에 "Mark activity as completed"라고 표시된 이미지가 있으며 사용자가 해당 액티비티를 클릭하면 다음 예시와 같이 Ajax POST를 수행합니다.

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: {},
        success: function (response) {
            // ....
        }
    });
});

어떻게 하면<%= Html.AntiForgeryToken() %> ? ?도우미 콜을 Ajax 콜의 데이터 파라미터에 포함시켜야 합니까?

투고가 길어서 죄송합니다.도와주셔서 감사합니다.

편집:

jayrdub 답변에 따라 다음과 같이 사용하였습니다.

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: {
            AddAntiForgeryToken({}),
            id: parseInt($(this).attr("title"))
        },
        success: function (response) {
            // ....
        }
    });
});

이렇게 간단한 js 함수를 사용합니다.

AddAntiForgeryToken = function(data) {
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
    return data;
};

페이지 상의 모든 폼은 토큰의 값이 같기 때문에 맨 위 마스터 페이지에 이와 같은 것을 넣습니다.

<%-- used for ajax in AddAntiForgeryToken() --%>
<form id="__AjaxAntiForgeryForm" action="#" method="post"><%= Html.AntiForgeryToken()%></form>  

다음으로 ajax call do (두 번째 예시와 일치하도록 편집)

$.ajax({
    type: "post",
    dataType: "html",
    url: $(this).attr("rel"),
    data: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
    success: function (response) {
        // ....
    }
});

360 Airwalk에서 제공하는 솔루션은 마음에 들지만 조금 개선될 수 있습니다.

은 ''를 때$.post()데이터일 jQuery를 .Content-Typeheader 이 경우 ASP.header('ASP')를합니다.NET MVC는 NET MVC를 사용합니다.따라서 헤더가 항상 존재하는지 확인해야 합니다.

또 다른 개선사항은 POST, PUT, DELETE 등의 콘텐츠를 가진 모든 HTTP 동사를 지원하는 것입니다.어플리케이션에서는 POST만 사용할 수 있지만 범용 솔루션을 사용하여 수신하는 모든 데이터에 위조 방지 토큰이 있는지 확인하는 것이 좋습니다.

$(document).ready(function () {
    var securityToken = $('[name=__RequestVerificationToken]').val();
    $(document).ajaxSend(function (event, request, opt) {
        if (opt.hasContent && securityToken) {   // handle all verbs with content
            var tokenParam = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
            opt.data = opt.data ? [opt.data, tokenParam].join("&") : tokenParam;
            // ensure Content-Type header is present!
            if (opt.contentType !== false || event.contentType) {
                request.setRequestHeader( "Content-Type", opt.contentType);
            }
        }
    });
});

그 밖에도 많은 답변이 있다는 것을 알지만, 이 기사는 훌륭하고 간결하며, 일부뿐 아니라 모든 Http Post를 확인해야 합니다.

http://richiban.wordpress.com/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/

폼 컬렉션을 수정하는 대신 HTTP 헤더를 사용합니다.

서버

//make sure to add this to your global action filters
[AttributeUsage(AttributeTargets.Class)]
public class ValidateAntiForgeryTokenOnAllPosts : AuthorizeAttribute
{
    public override void OnAuthorization( AuthorizationContext filterContext )
    {
        var request = filterContext.HttpContext.Request;

        //  Only validate POSTs
        if (request.HttpMethod == WebRequestMethods.Http.Post)
        {
            //  Ajax POSTs and normal form posts have to be treated differently when it comes
            //  to validating the AntiForgeryToken
            if (request.IsAjaxRequest())
            {
                var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];

                var cookieValue = antiForgeryCookie != null
                    ? antiForgeryCookie.Value 
                    : null;

                AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);
            }
            else
            {
                new ValidateAntiForgeryTokenAttribute()
                    .OnAuthorization(filterContext);
            }
        }
    }
}

고객

var token = $('[name=__RequestVerificationToken]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;

$.ajax({
    type: 'POST',
    url: '/Home/Ajax',
    cache: false,
    headers: headers,
    contentType: 'application/json; charset=utf-8',
    data: { title: "This is my title", contents: "These are my contents" },
    success: function () {
        ...
    },
    error: function () {
        ...
    }
});

여기서는 고급 네크로맨서처럼 느껴지지만, 이것은 4년 후에도 MVC5에서 여전히 이슈가 되고 있습니다.

Ajax 요구를 올바르게 처리하려면 Ajax 콜 시 위조 방지 토큰을 서버에 전달해야 합니다.포스트 데이터나 모델에 통합하는 것은 복잡하고 불필요합니다.토큰을 커스텀헤더로 추가하는 것은 깔끔하고 재사용할 수 있습니다.또한 매번 토큰을 추가하는 것을 잊지 않도록 설정할 수 있습니다.

예외는 있습니다.Ajax 콜에 대해 방해받지 않는Ajax는 특별한 처리가 필요하지 않습니다.토큰은 일반 숨김 입력 필드에서 정상적으로 전달됩니다.통상의 POST와 똑같습니다.

_Layout.cshtml

_layout.cshtml에는 이 JavaScript 블록이 있습니다.토큰을 DOM에 쓰는 것이 아니라 jQuery를 사용하여 MVC Helper가 생성하는 숨겨진 입력 리터럴에서 추출합니다.헤더 이름인 Magic 문자열은 속성 클래스에서 상수로 정의됩니다.

<script type="text/javascript">
    $(document).ready(function () {
        var isAbsoluteURI = new RegExp('^(?:[a-z]+:)?//', 'i');
        //http://stackoverflow.com/questions/10687099/how-to-test-if-a-url-string-is-absolute-or-relative

        $.ajaxSetup({
            beforeSend: function (xhr) {
                if (!isAbsoluteURI.test(this.url)) {
                    //only add header to relative URLs
                    xhr.setRequestHeader(
                       '@.ValidateAntiForgeryTokenOnAllPosts.HTTP_HEADER_NAME', 
                       $('@Html.AntiForgeryToken()').val()
                    );
                }
            }
        });
    });
</script>

beforeSend 함수의 작은 따옴표 사용에 유의하십시오.- 렌더링되는 입력 요소는 JavaScript 리터럴을 깨는 큰 따옴표를 사용합니다.

클라이언트 JavaScript

이렇게 하면 위의 beforeSend 함수가 호출되고 AntiForgy가 실행됩니다.토큰은 요청 헤더에 자동으로 추가됩니다.

$.ajax({
  type: "POST",
  url: "CSRFProtectedMethod",
  dataType: "json",
  contentType: "application/json; charset=utf-8",
  success: function (data) {
    //victory
  }
});

서버 라이브러리

비표준 토큰을 처리하려면 사용자 지정 특성이 필요합니다.이것은 @viggity의 솔루션을 기반으로 하지만 방해받지 않는 아약스를 올바르게 처리합니다.이 코드는 공통 라이브러리에 저장할 수 있습니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ValidateAntiForgeryTokenOnAllPosts : AuthorizeAttribute
{
    public const string HTTP_HEADER_NAME = "x-RequestVerificationToken";

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var request = filterContext.HttpContext.Request;

        //  Only validate POSTs
        if (request.HttpMethod == WebRequestMethods.Http.Post)
        {

            var headerTokenValue = request.Headers[HTTP_HEADER_NAME];

            // Ajax POSTs using jquery have a header set that defines the token.
            // However using unobtrusive ajax the token is still submitted normally in the form.
            // if the header is present then use it, else fall back to processing the form like normal
            if (headerTokenValue != null)
            {
                var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];

                var cookieValue = antiForgeryCookie != null
                    ? antiForgeryCookie.Value
                    : null;

                AntiForgery.Validate(cookieValue, headerTokenValue);
            }
            else
            {
                new ValidateAntiForgeryTokenAttribute()
                    .OnAuthorization(filterContext);
            }
        }
    }
}

서버/컨트롤러

이제 Atribute를 Action에 적용하기만 하면 됩니다.컨트롤러에 Atribute를 적용하면 모든 요구가 검증됩니다.

[HttpPost]
[ValidateAntiForgeryTokenOnAllPosts]
public virtual ActionResult CSRFProtectedMethod()
{
  return Json(true, JsonRequestBehavior.DenyGet);
}

HTML을 사용하지 마십시오.위조 방지토큰 대신 위조 방지 기능을 사용하십시오.겟토큰위조방지.ASP에서의 CSRF(Cross-Site Request Formature) 공격 방지 설명에 따라 Web API에서 검증합니다.NET MVC 어플리케이션

당신이 해야 할 일은 '_RequestVerification'이Token" 입력이 POST 요청에 포함됩니다.나머지 절반의 정보(사용자 쿠키의 토큰)는 이미 AJAX POST 요청과 함께 자동으로 전송됩니다.

예.,

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: { 
            "__RequestVerificationToken":
            $("input[name=__RequestVerificationToken]").val() 
        },
        success: function (response) {
            // ....
        }
    });
});

저는 지금 하고 있는 프로젝트에서 이 실제 문제를 구현하고 있었습니다.인증된 사용자를 필요로 하는 모든 ajax-POST에 대해 실행했습니다.

우선, 나는 너무 자주 같은 말을 반복하지 않기 위해 jquery ajax 전화를 걸기로 결정했다.이 javascript 스니펫은 모든 Ajax(포스트) 콜이 내 요청 검증 토큰을 요청에 추가하도록 보장합니다.주의: 이름 __RequestVerification토큰은 에 의해 사용됩니다.다음과 같이 표준 Anti-CSRF 기능을 활용할 수 있는 네트워크 프레임워크입니다.

$(document).ready(function () {
    var securityToken = $('[name=__RequestVerificationToken]').val();
    $('body').bind('ajaxSend', function (elm, xhr, s) {
        if (s.type == 'POST' && typeof securityToken != 'undefined') {
            if (s.data.length > 0) {
                s.data += "&__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
            else {
                s.data = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
        }
    });
});

위의 javascript에서 토큰을 사용할 수 있어야 하는 보기에서 공통 HTML-Helper를 사용하십시오.기본적으로 이 코드를 원하는 위치에 추가할 수 있습니다.나는 그것을 if(요청) 안에 두었다.IsAuthenticated) 스테이트먼트:

@Html.AntiForgeryToken() // you can provide a string as salt when needed which needs to match the one on the controller

컨트롤러에서는 표준 ASP를 사용하기만 하면 됩니다.Net MVC Anti-CSRF 메커니즘(실제로 Salt를 사용했지만) 이렇게 했습니다.

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public JsonResult SomeMethod(string param)
{
    // do something
    return Json(true);
}

Firebug 등의 툴을 사용하면 POST 요구에 __RequestVerification이 어떻게 설정되어 있는지 쉽게 알 수 있습니다.토큰 파라미터가 추가되었습니다.

이것도 할 수 있습니다.

$("a.markAsDone").click(function (event) {
    event.preventDefault();

    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: $('<form>@Html.AntiForgeryToken()</form>').serialize(),
        success: function (response) {
        // ....
        }
    });
});

는 '어느 정도 쓸 수 있다'를 쓰는 예요.Razor ,를 사용하고 WebForms은 " " "와 할 수 있습니다.<%= %> 표시

그 과정에서 저를 도와준 @JBall의 답변에 대한 저의 코멘트와 더불어, 이것이 저에게 맞는 최종 답변입니다.MVC와 Razor를 사용하고 있으며, jQuery AJAX를 사용하여 폼을 제출하고 있습니다.새로운 결과로 부분 뷰를 갱신할 수 있도록 하기 위해 완전한 포스트백(및 페이지 플리커)을 하고 싶지 않았습니다.

, 그럼 여기에다가 더해져요.@Html.AntiForgeryToken()평소처럼 폼 안에.

AJAX 송신 버튼 코드(온클릭 이벤트)는 다음과 같습니다.

//User clicks the SUBMIT button
$("#btnSubmit").click(function (event) {

//prevent this button submitting the form as we will do that via AJAX
event.preventDefault();

//Validate the form first
if (!$('#searchForm').validate().form()) {
    alert("Please correct the errors");
    return false;
}

//Get the entire form's data - including the antiforgerytoken
var allFormData = $("#searchForm").serialize();

// The actual POST can now take place with a validated form
$.ajax({
    type: "POST",
    async: false,
    url: "/Home/SearchAjax",
    data: allFormData,
    dataType: "html",
    success: function (data) {
        $('#gridView').html(data);
        $('#TestGrid').jqGrid('setGridParam', { url: '@Url.Action("GetDetails", "Home", Model)', datatype: "json", page: 1 }).trigger('reloadGrid');
    }
});

MvcJqGrid를 포함하는 부분 보기가 어떻게 업데이트되고 있고 어떻게 새로고침되는지 보여 주는 "성공" 액션은 에 남겨두었습니다(매우 강력한 jqGrid 그리드이며, 이는 이를 위한 훌륭한 MVC 래퍼입니다.

컨트롤러 방식은 다음과 같습니다.

    //Ajax SUBMIT method
    [ValidateAntiForgeryToken]
    public ActionResult SearchAjax(EstateOutlet_D model) 
    {
        return View("_Grid", model);
    }

모든 폼의 데이터를 모델로서 POST 하는 것을 좋아하지 않는 것은 인정합니다만, 필요한 경우는, 이것도 하나의 방법입니다.MVC는 데이터 바인딩을 너무 쉽게 하기 때문에 16개의 개별 값(또는 약한 타입의 Form Collection)을 제출하는 것이 아니라 이 방법은 괜찮다고 생각합니다.만약 당신이 더 잘 알고 있다면, 저는 강력한 MVC C# 코드를 제작하고 싶기 때문에 알려주시기 바랍니다.

https://gist.github.com/scottrippey/3428114에서 $.199 콜마다 요청을 수정하고 토큰을 추가할 수 있는 매우 현명한 아이디어를 발견했습니다.

// Setup CSRF safety for AJAX:
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    if (options.type.toUpperCase() === "POST") {
        // We need to add the verificationToken to all POSTs
        var token = $("input[name^=__RequestVerificationToken]").first();
        if (!token.length) return;

        var tokenName = token.attr("name");

        // If the data is JSON, then we need to put the token in the QueryString:
        if (options.contentType.indexOf('application/json') === 0) {
            // Add the token to the URL, because we can't add it to the JSON data:
            options.url += ((options.url.indexOf("?") === -1) ? "?" : "&") + token.serialize();
        } else if (typeof options.data === 'string' && options.data.indexOf(tokenName) === -1) {
            // Append to the data string:
            options.data += (options.data ? "&" : "") + token.serialize();
        }
    }
});

1. 서버에서 토큰을 가져오는 기능의 정의

@function
{

        public string TokenHeaderValue()
        {
            string cookieToken, formToken;
            AntiForgery.GetTokens(null, out cookieToken, out formToken);
            return cookieToken + ":" + formToken;                
        }
}

2. 서버로 전송하기 전에 토큰을 가져와 헤더를 설정합니다.

var token = '@TokenHeaderValue()';    

       $http({
           method: "POST",
           url: './MainBackend/MessageDelete',
           data: dataSend,
           headers: {
               'RequestVerificationToken': token
           }
       }).success(function (data) {
           alert(data)
       });

3. Post/get 처리 메서드의 HttpRequestBase 온서버 검증

        string cookieToken = "";
        string formToken = "";
        string[] tokens = Request.Headers["RequestVerificationToken"].Split(':');
            if (tokens.Length == 2)
            {
                cookieToken = tokens[0].Trim();
                formToken = tokens[1].Trim();
            }
        AntiForgery.Validate(cookieToken, formToken);

먼저 @Html을 사용합니다.위조 방지html의 토큰()

 $.ajax({
        url: "@Url.Action("SomeMethod", "SomeController")",
        type: 'POST',
        data: JSON.stringify(jsonObject),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        async: false,
        beforeSend: function (request) {
            request.setRequestHeader("RequestVerificationToken", $("[name='__RequestVerificationToken']").val());
        },
        success: function (msg) {
            alert(msg);
        }

이 질문이 올라온 지 꽤 지났지만 위조 방지 사용에 대해 설명하는 유용한 자료를 찾았습니다.토큰을 사용하여 번거로움을 덜 수 있습니다.또한 AJAX 호출에 위조 방지 토큰을 쉽게 포함하기 위한 jquery 플러그인도 제공합니다.

ASP용 위조 방지 요청 레시피NET MVC 및 AJAX

내가 기여하는 건 별로 없지만, 누군가 유용하다고 생각할지도 몰라.

여기 내가 본 것 중 가장 쉬운 방법이 있다.주의: "@Html"이 있는지 확인합니다.위조 방지[ Token ( ) ]를 표시합니다.

  $("a.markAsDone").click(function (event) {
        event.preventDefault();
        var sToken = document.getElementsByName("__RequestVerificationToken")[0].value;
        $.ajax({
            url: $(this).attr("rel"),
            type: "POST",
            contentType: "application/x-www-form-urlencoded",
            data: { '__RequestVerificationToken': sToken, 'id': parseInt($(this).attr("title")) }
        })
        .done(function (data) {
            //Process MVC Data here
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            //Process Failure here
        });
    });

360Airwalk 솔루션의 약간의 개선.이것은 javascript 함수에 위조방지 토큰을 포함하기 때문에 @Html.위조 방지Token()은 모든 뷰에 포함할 필요가 없습니다.

$(document).ready(function () {
    var securityToken = $('@Html.AntiForgeryToken()').attr('value');
    $('body').bind('ajaxSend', function (elm, xhr, s) {
        if (s.type == 'POST' && typeof securityToken != 'undefined') {
            if (s.data.length > 0) {
                s.data += "&__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
            else {
                s.data = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
        }
    });
});
function DeletePersonel(id) {

    var data = new FormData();
    data.append("__RequestVerificationToken", "@HtmlHelper.GetAntiForgeryToken()");

    $.ajax({
        type: 'POST',
        url: '/Personel/Delete/' + id,
        data: data,
        cache: false,
        processData: false,
        contentType: false,
        success: function (result) {
        }
    });
}

public static class HtmlHelper {
    public static string GetAntiForgeryToken() {
        System.Text.RegularExpressions.Match value = 
                System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml().ToString(), 
                        "(?:value=\")(.*)(?:\")");
        if (value.Success) {
            return value.Groups[1].Value;
        }
        return "";
    }
}

삭제 메서드를 실행하기 위해 ajax 포스트를 사용하고 있습니다(visjs 타임라인에서 가져온 것이지만 그것은 관련이 없습니다).이건 내 여동생이야

이것은 Index.cshtml 입니다.

@Scripts.Render("~/bundles/schedule")
@Styles.Render("~/bundles/visjs")
@Html.AntiForgeryToken()

<!-- div to attach schedule to -->
<div id='schedule'></div>

<!-- div to attach popups to -->
<div id='dialog-popup'></div>

여기에 덧붙인 건@Html.AntiForgeryToken()토큰을 페이지에 표시시키다

그리고 나서 나는 아약스 포스트에서 다음과 같이 썼다.

$.ajax(
    {
        type: 'POST',
        url: '/ScheduleWorks/Delete/' + item.id,
        data: {
            '__RequestVerificationToken': 
            $("input[name='__RequestVerificationToken']").val()
              }
     }
);

그러면 페이지에서 삭제한 토큰 값이 게시된 필드에 추가됩니다.

이전에 헤더에 값을 입력하려고 했지만 동일한 오류가 발생했습니다.

개선 사항을 자유롭게 게시하십시오.이것은 확실히 내가 이해할 수 있는 간단한 접근법인 것 같다.

네, 여기 많은 게시물이 있습니다.그들 중 어느 것도 도움이 되지 않았습니다.구글을 며칠이고 몇 일이고 사용할 수 없습니다.그리고 앱 전체를 처음부터 다시 작성해야 할 지경에 이르렀습니다.그리고 웹에 작은 덩어리가 있는 것을 알게 되었습니다.confg

 <httpCookies requireSSL="false" domain="*.localLookup.net"/>

왜 추가했는지 이유를 알 수 없습니다.실가동 모드가 아닌 디버깅 모드에서는 무시됩니다(IE Installed to IIS Something).

솔루션에는 2가지 옵션 중 하나가 있었습니다.왜 추가했는지 기억이 나지 않기 때문에 다른 것에 의존하지 않는지 확신할 수 없습니다.두 번째로 도메인 이름은 모두 소문자여야 하며 *.localLookup.net에서 했던 것과 달리 TLD여야 합니다.

도움이 안 될 수도 있어요그게 누군가에게 도움이 됐으면 좋겠다.

제가 찾은 해결책은 ASPX가 아니라 Razor용이지만 상당히 이해하기 쉬운 문제입니다.

요청에 AntiForgy를 추가하여 해결했습니다.HTML 도우미는 콜을 사용하여 HTML ID를 생성하지 않습니다.

@Html.AntiForgeryToken()

포스트 리퀘스트에 토큰을 추가하기 위해 숨겨진 필드에 jquery를 사용하여 AntiForgy ID를 추가했습니다.

$("input[name*='__RequestVerificationToken']").attr('id', '__AjaxAntiForgeryForm');

이로 인해 컨트롤러는 [Validate]를 사용하여 요청을 수락했습니다.위조 방지토큰]아트리뷰트

위조 방지토큰은 여전히 골칫거리입니다. 위의 예들 중 어느 것도 제게는 한마디로 통하지 않습니다.너무 많아.그래서 다 합쳐봤어요.@Html이 필요합니다.위조 방지Iirc에 걸려있는 형태의 토큰

다음과 같이 해결:

function Forgizzle(eggs) {
    eggs.__RequestVerificationToken =  $($("input[name=__RequestVerificationToken]")[0]).val();
    return eggs;
}

$.ajax({
            url: url,
            type: 'post',
            data: Forgizzle({ id: id, sweets: milkway }),
});

확실하지 않은 경우 $ 기호를 추가합니다.

언급URL : https://stackoverflow.com/questions/4074199/jquery-ajax-calls-and-the-html-antiforgerytoken

반응형