I'm trying to deal with: "Requests made from Javascript running on your web pages must be proxied to avoid same-origin policy conflicts."
I know how to work with the JSON once I've got it. But aside from copy-pasting the JSON results via my browser, I don't know how to localize it for use.
Did you tried
$.getJSON('url', function(data){
//do smth with data
})
?
After the request is complete, data will be an object with all JSON response and you can access it as regular js object: data.something and so on.
Related
I am used to creating webapplications with Wicket. There it is possible to generate a HTML page using POST, receiving a large JSON from the client (browser) to generate some charts. This can be done for example with CURL.
In Angular, I could not find a similar approach.
What is the recommended way to render a chart based on the JSON that a browser provides? An URL parameter is not really the way to go as the URL length is limited.
I can think of a work-around wheren I first post the data to some webservice, receive an id, and then pass that id to an URL in Angular, but that seems a lot of work for something simple :)
It took me a while to understand this, being that it was a little obvious. I will answer myself, so other can benefit of the answer and ofcourse to see if there's a better way to do this. The problem was based on Axios/Yii2 but I guess this will apply equally to other frontend libraries/frameworks sending data to Yii2.
I needed to post data from a small form made on Vuejs, sending the request Axios to a Action/Controller on Yii2, so data is sent on a simple POST request and the post is getting to the controller, but I was not able to receive the data on the action, $_POST | $post arrives empty (checked using xdebug).
As much as I remember, this had something to do with security. But I already tried by disabling public $enableCsrfValidation, so that was not the problem.
public $enableCsrfValidation = false;
But no matter what, data was not being added to the request/post data inside Yii2.
The following Image, explains the problem you will find there:
The Axisos method that sends the post with test data.
The Yii2 Action stpoed at the place, I should be able to see data.
The capture of the xdebug variables and data for the request.
The capture of Chrome where you can check the payload is sent.
The answer is as I said "kind of obvious", but I could not see that, and I am sure some other devs will probably fall on this.
After searching like crazy and asking everyone, I tried sending the request by using Postman app, yup the best thing I know to test apis.
Dont forgue to add the xdebug cookie to be able to debug your PHP Endpoint.
There I found the first clue «the obvious part», I was not sending data as a form-data, Axios and other libraries, send the data as a raw (application/json) payload.
This means that Yii2 will no be able to find the data inside the post request, yes its there but Yii2 magic will not work, neither you will find this data inside $GLOBALS or in $_POST.
So reading the Yii2 documentation I found that inside request I can use a function that will help me recovering the Raw data, so to do this use the following line:
$raw_data = Yii::$app->request->getRawBody();
Now, that data gets to you as a simple, raw json string, so use the power of PHP to parse it to an object.
$object= json_decode($raw_data );
And finally use the data inside by calling the properties you look for, sent on the pay load:
Json Payload:
{
"msg":"This is my payload",
"id":"11"
}
To use it:
echo $object->{'msg'}; // prints: This is my payload
So that's the way to handle that, now I would like some other points of view to see if there's a better way or cleaner way to do this. Hope it helps.
I want to practice with JSON and AJAX with HTML pages only (no PHP, no asp.NET, no ruby, no Web server locally installed). I want to create web page which will produce JSON data as result for test AJAX request.
Is it possible?
ADDED:
Lets change it a bit, suppose that I have a webpage (no asp.net, no php).
How to create web page with will output Json data with header set to
header('Content-Type: application/json');
You can give the AJAX request url as "file:///D:/test.txt"
I think IE allows it and Chrome doesn't. And I'm not sure if all versions of IE support it.
Ofcourse this 'response' will be static. It wont change based on your request inputs.
JSON are just javascript objects. What you can do is, instead of invoking the real ajax requests, do a mock request that fetch the locally declared json. For e.g.
jQuery (A concrete implementation)
$.get("ajax/test.html", function( data ) {
console.log(data);
alert( "Load was performed." );
});
Mock implementation
Create a fake json "factory"
var MockJson = (function () {
return { "mockObject" : "mockValue" };
})();
console.log(MockJson);
Of course my example is trivial, you can use the response to manipulate the DOM or display the value somewhere.
I am working on a mobile app. Since I wanted a solution that would work on multiple platforms, I started with Cordova. As I have much data to handle and many views, I decided to use Ember.
I need to use three different JSON datasets that are updated rather frequently in the database. To enable the mobile app to work offline, I will have to store the JSON data, as well as update them when the database is changed.
Questions
How can I retrieve JSON from another server(CORS blocked)?
How can the retrieved JSON be saved on device? [HTML5 LocalStorage(preferred) or FileAPI]
How to read JSON file and send data as model to templates? (I guess Ember.$.getJSON can do this)
Any help is welcome. Thanks!
Update 1
Since I ran into many issues using Ember-data, I am not using it in my app.
Found this link for cross-domain with ajax
Update 2
CORS can be solved only by JSONP or by setting ACCESS-CONTROL-ALLOW-ORIGIN in the reponse of the server(I tried many other solutions, and failed)
Since the api is in my server, I did the latter.
For 2 and 3, I think I could use this SO question
This is what I found out :
JSON data from a server in different domain
You cannot read JSON data from a server in another domain. This is due to the Same-origin policy implemented in browsers. A browser will retrieve your JSON but will not allow you access to the same. There are two solutions(AFAIK) to this problem :
Using JSONP - I'm not going into the details, but there are many links available for this.
Allow CORS from server - When the server sends JSONified data, you can add additional headers for ACCESS-CONTROL-ALLOW-ORIGIN. After retrieving the JSON from server, the browser checks for this header to either block or allow CORS. I used some decorators for adding crossdomain headers and then my data was successfully read in the browser.
Saving the json data
HTML5 makes everything easier. In your javascript, you just have to use :
localStorage["application.state.data"] = JSON.stringify(json);
or
localStorage.setItem("application.state.data", JSON.stringify(json));
Retrieve works just the same
var data = JSON.parse(localStorage["application.state.data"]);
or
var data = JSON.parse(localStorage.getItem("application.state.data"));
I am following the tutorial in the CakePHP book that explains the basics of setting up a RESTful web service.
So far, I've updated my routes file to the following:
Router::mapResources('stores');
Router::parseExtensions('json');
I have also setup a blank layout in app/layouts/json and the appropriate json views. I am receiving my json output successfully when I navigate to controller/action.json
I am wondering though, without the.json extension it attempts to load the regular view. I am looking to build a pure api with only json output, is there any way to prevent regular render output instead?
You could force a rendering as JSON if you can recognise a JSON request another way. For example, if the Accepts HTTP header contains application/json, you could put this in your controller:
public function beforeFilter(){
if ($this->request->accepts('application/json')) {
$this->RequestHandler->renderAs($this, 'json');
}
parent::beforeFilter();
}
It's CakePHP 2.0 notation, but something similar probably exists for CakePHP 1.2 and 1.3.
You could also detect the request Content-Type instead, or as well, especially if Accepts is not used.
What are you seeing at the moment? If you've used bake Cake may have generated the views for you?
Just delete the views in /app/views/layout and /app/views/controllername
If you are trying to prevent the request from hitting the controller at all then I'm not so sure, you could just update your .htaccess file to only send requests ending in .json to the app or something similar.
here is what i did.
if i know i'm building only json API, i added to my AppController.php following:
public function beforeFilter()
{
if (empty($this->request->params['ext']) || $this->request->params['ext'] != "json")
{
$this->render(FALSE, 'maintenance'); //no view, only layout
$this->response->send();
$this->_stop();
}
}
and in my /app/Layouts/maintenance.ctp
echo __('Invalid extension');
this way all requests without the json extension will end up on the "maintenance" page where you can put any info you want, i'm planning to put there link to API docs.